LINUX.ORG.RU

юнионы в C++

 


1

4

Пишу телегу против плюсов. В связи с этим вопрос - насколько широко в плюсах используются нуль-терминированные строки, юнионы, неумные указатели и всё такое плохое, что делает Си опасным языком.

Даже интересует не столько то, насколько они используются в существующих программах, а есть ли примеры программ, где хорошие средства плюсов сконсолидировались и поставили заслон от опасных конструкций Си, позволив полностью избежать их использования и избавиться от типичных ошибок Си. Можно ли так написать что-то существенно сложное? Сделано ли это в любимых библиотеках (Буст, QT и иже с ними)? Вторая часть вопроса - это неопределённое поведение. В Си его много. Это подаётся как фича, но с точки зрения безопасности это дыра. Меньше ли неопределённого поведения в С++?

Есть две полярные точки зрения на вопрос:

а) С++ перекрывает Си, поэтому там всё сделано по-другому, поэтому безопасность выше б) С++ - наследник Си и в целом наследует его недостатки.

Поскольку я мало пишу на Си и ещё меньше на Си++, у меня нет сложившегося мнения на эту тему. А у ЛОРа наверняка есть мнение, даже несколько.

★★★★★

Краткий ответ - это зависит от людей, которые писали, но в целом отсутствие каких-либо вещей в стандартной библиотеке, не означает, что этого нет в других библиотеках или же нельзя написать своё, чтобы локализовать небезопасный код.

нуль-терминированные строки,

Это ты так char* назвал? Так-то для обеспечения совместимости с C API std::basic_string<> тоже держит строку нуль-терминированной. char* без оберток уже давно не используется, даже для не владеющих строк делали свои классы a la std::string_view.

юнионы

boost::variant уже давно существует, или же использовали наследование. Дело в том, что до С++11 union с классами с нетривиальными конструкторами и деструктором использовать было нельзя.

неумные указатели

Ещё до С++11 делали либо свои умные указатели, либо из библиотек использовали (того же boost).

Из библиотек, те же Boost, Qt, Poco.

Что касается UB - оно есть, никуда не делось, и его надо учитывать при написании программ. Это тоже типа фича, простор для оптимизации.

Begemoth ★★★★★ ()
Последнее исправление: Begemoth (всего исправлений: 1)

Пишу телегу против плюсов.

Сишники пишут на Си, плюсовики на Си++, питонисты на Питоне, даже хаскеллисты пишут на Хаскелле. Одни растаманы вместо того чтобы писать на Расте, пишут «телеги против плюсов»

нуль-терминированные строки, юнионы, неумные указатели и всё такое плохое

Плюсовики в своей массе прагматичны и им чужды ура-вопли. Плюсовики не считают всё это «таким плохим». И даже goto. Плюсовики используют возможности языка в той мере, в какой эти средства уместны и отвечают текущим задачам.

у меня нет сложившегося мнения на эту тему

Вот поэтому распрягай свою «телегу против плюсов» и займись чем-то полезным на своём привычном языке.

Usruser ()

С++ не знаю, но очевидно что для решения проблем:

нуль-терминированные строки

std::string, std::string_view, std::span хранят размер

юнионы

std::variant позволяет безопасно получить хранимые данные

MOPKOBKA ()
Последнее исправление: MOPKOBKA (всего исправлений: 1)

Пишу телегу против плюсов

Зачем? Пиши телегу против раста. Цпп уже очень старый, все срачи уже давно прошли, а участвующие состарились и умерли.

используются нуль-терминированные строки

Активно. Вообще в c++ строк нет. std::string не далеко ушёл от std::vector<char>.

юнионы

В современном цпп есть замена в виде std::variant

неумные указатели

дофига и больше. Никогда от них не уйдут.

ox55ff ★★★★★ ()

одновременное наличие тезисов «Пишу телегу против плюсов» и «мало пишу на Си и ещё меньше на Си++» говорит об отсутствии логики и последовательности действий. Любой ответ теряет смысл.

MKuznetsov ★★★★★ ()
Ответ на: комментарий от MKuznetsov

Почему? Может, у чувака годный вброс будет. Ну либо ему пытаются продать разработку проекта на C++, а он хочет свою жопу прикрыть.

hateyoufeel ★★★★★ ()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от Begemoth

Спасибо. Интересно, что получился спектр мнений. А есть ли операционки, написанные на С++ и сколько-нибудь влиятельные?

Насчёт использования обёрток над нуль-терминированными строками - если у нас API на Си (допустим, в Линуксе), то получается, что нужно обернуть всё API в эти обёртки, т.е. получается дополнительная цена, в т.ч. в производительности, а опасность остаётся, просто она как будто локализована в обёртках (так ли это и не просочится ли на практике беда сквозь них - мне тоже неясно и было бы интересно узнать).

den73 ★★★★★ ()

А мне очень хочется поругать хаскель, но я его совершенно не знаю. Поругайте мне хаскель, пожалуйста. Спасибо.

thesis ★★★★★ ()
Ответ на: комментарий от thesis

Лехко! В хачкелле для указания типа пишут ::, а для создания списка :. А в ML и других ML-подобных языках наоборот: : для указания типа и :: для работы со списками. И есть реально куча людей, которых это бесит. Они обычно фанаты OCaml все.

hateyoufeel ★★★★★ ()
Ответ на: комментарий от den73

Операционки или ядра ОС?

Header-only обёртки позволяют компилятору заинлайнить их и исключить потери производительности. Полностью исключить возможность выстрелить себе в ногу в С++ нельзя (кстати и в Haskell тоже нельзя с его unsafeCoerce), важно что код получается safe by default.

Begemoth ★★★★★ ()
Ответ на: комментарий от Usruser

Вот поэтому распрягай свою «телегу против плюсов» и займись чем-то полезным на своём привычном языке.

Плюсую.

hobbit ★★★★★ ()
Ответ на: комментарий от alysnix

Ну на самом деле, в плюсах есть вещи, которые меня, человека, который на них пишет, люто выбешивают. Примеры — отсутствие модульности и отсутствие нормальных строк (нормальные — это которые для людей, а не для Доказательства Универсальности Библиотеки Шаблонов).

Модульность вроде как поправили в C++20. Каюсь, ещё не тыкал, ибо для моей повседневной работы требование C++20 пока неприемлемо. Но собираюсь.

Как сделаны строки для людей — можно посмотреть на примере QString из QtCore (правда, сами кутешники в 6-й ветке начали их скатывать в самизнаетечто).

hobbit ★★★★★ ()
Ответ на: комментарий от hobbit

Как сделаны строки для людей — можно посмотреть на примере QString из QtCore

если не нравятся божественные строки от самого с++, можно написать свои божественные строки - как Qstring. и это тоже С++.

alysnix ()
Ответ на: комментарий от X512

Фуксия выглядит чем-то довольно известным.

den73 ★★★★★ ()
Ответ на: комментарий от den73

раст - язык сатанинский. a c++ - божественный. исходить надо из этого, тогда жизнь заиграет новыми красками.

alysnix ()

смотря какой стандарт языка. в целом всех «ошибок си» можно избежать, да. просто другой вопрос, что программисты часто не возьмут в толк как так сделать. но есть умные указатели, строковые литералы (чтобы избавится от си строк) и прочее.

но при взаммодействие с си либами этого не избежать. но ты можешь создать обертку (как вобщем то и нужно) и юзать ее. там будут раии и прочие фишки. только, опять же, часто программисты не утруждают себя делать нормально.

зы: весь тред не читал, сорян если что

zerhud ()
Ответ на: комментарий от den73

спектр мнений.

вот именно. нужно больше конкретики.

zerhud ()
Ответ на: комментарий от Usruser

Поддержка Юникода в классе строки вообще не нужна. Достаточно простой обёртки над char*.

X512 ★★★ ()
Ответ на: комментарий от hobbit

отсутствие нормальных строк

нормальные строчки отсутствуют не в языке, а в голове программиста. до сих пор находятся чудаки, которые пытаются посчитать кол-во символов методом size, разделить слова по пробелам, и прочее.. строчка это строчка, просто данные. если хочешь работать как-то иначе, чем с контейнером байт, то нужно icu (boost.locale например).

zerhud ()
Ответ на: комментарий от X512

адекватно - это запретить вся языки кроме английского и русского. чтобы было: одна буква - один байт.

просто запретить на совете безопасности оон, и положить конец всем этим уникодам.

alysnix ()
Ответ на: комментарий от Usruser

Одни растаманы вместо того чтобы писать на Расте, пишут «телеги против плюсов»

Лол, а ты точно автора знаешь? Он типа лиспер и подозреваю, что о расте знает ещё меньше, чем о плюсах.

DarkEld3r ★★★★★ ()
Ответ на: комментарий от DarkEld3r

В данном случае не важно какой ИМЕННО язык для него родной. Я просто ткнул пальцем в небо. Обычно такой фигнёй занимаются программисты на Раст.

Usruser ()
Ответ на: комментарий от zerhud

то нужно icu (boost.locale например)

которое даже не является частью стандартной библиотеки языка (так же, как и QtCore, впрочем).

hobbit ★★★★★ ()

Ладно, в общем я прихожу к выводу, что всё примерно так, как я и предполагал: в теории, С++ помогает существенно повысить безопасность по сравнению с Си. На практике, этому мешают:

  • отсутствие канонического способа писать на С++
  • наличие сишных API
  • недостаток квалификации

Поэтому повышение безопасности достижимо, но не кардинальное. Похоже на правду?

den73 ★★★★★ ()
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от zerhud

голосую за английский и эсперанто тогда :)

зачем эсперанто? на лоре его не знает никто.

alysnix ()

но с точки зрения безопасности это дыра

Напиши телегу против бензопил и прочих острых инструментов, которыми многие случайно устраняют себе выступающие части :) С точки зрения безопасности у людей есть фатальный недостаток :))

slackwarrior ★★★★★ ()

Есть две полярные точки зрения на вопрос:

а) С++ перекрывает Си, поэтому там всё сделано по-другому, поэтому безопасность выше б) С++ - наследник Си и в целом наследует его недостатки.

Истина как обычно где-то посередине. Да, в С++ есть зерокост абстракции, повышающие безопасность, типа стандартных контейнеров, полоумных указателей, std::variant и т.д. Полной безопасности они конечно не дают, но позволяют писать более-менее рабочий код после многолетнего опыта забега по граблям. С другой стороны С++ полностью наследует все недостатки и UB из С, на которых по невнимательности подрываются даже опытные крестовики. Например мое любимое UB месяца:

#include <iostream>

int do_nothing() {
    std::cout << "do_nothing" << std::endl;
}

int launch_missiles() {
    std::cout << "launch_missiles" << std::endl;
}

int main() {
    do_nothing();
    return 0;
}
$ g++ -O2 test.cpp -o test
$ ./test
do_nothing
launch_missiles
launch_missiles
launch_missiles
launch_missiles
launch_missiles

и так далее до бесконечности.

archie ()
Ответ на: комментарий от alysnix

А еще опытные крестовики никогда не ошибаются, всегда пишут только корректный код, не допускают никаких UB, всегда фиксят все варнинги до последнего. У опытных крестовиков никогда не бывает проектов, высирающих тонны варнингов в сторонних хедерах, среди которых легко теряются варнинги в собственном коде. Знаем, плавали.

archie ()
Ответ на: комментарий от den73

Поэтому повышение безопасности достижимо, но не кардинальное. Похоже на правду?

Похоже, но аргументация против С++ слабовата. Так ты свою телегу против С++ никому не продашь. Сейчас даже джуниоры начинают обучение сразу с С++17, а с опытом приходит умение срезать острые углы. Я бы не сказал, что на практике это шибко серьезные недостатки. По мне так у С++ есть проблемы поважнее:

  • Отсутствие центрального репозитория типа npm, PyPI, maven и т.д. из за чего по статистике жыдбрейнса большинство крестовиков заталкивают исходники библиотек или даже скомпиленные бинари прямо себе в репу и везде таскают с собой.
  • Отсутствие нормального пакетного менеджера и системы сборки типа Cargo. Омерзительный шлак autotools и прочие процедурные симейки прилагаются.
  • Отсутствие нормальной системы модулей. И нет, C++20 ни разу не панацея, никто старые кодовые базы на них переводить не будет, модули так и будут сосуществовать с инклудами в общей помойке.
archie ()
Ответ на: комментарий от archie

Отсутствие центрального репозитория типа npm, PyPI, maven и т.д. из за чего по статистике жыдбрейнса большинство крестовиков заталкивают исходники библиотек или даже скомпиленные бинари прямо себе в репу и везде таскают с собой.

https://mesonbuild.com/Wrapdb-projects.html

Отсутствие нормального пакетного менеджера и системы сборки типа Cargo. Омерзительный шлак autotools и прочие процедурные симейки прилагаются.

Meson

X512 ★★★ ()
Ответ на: комментарий от archie

А еще опытные крестовики никогда не ошибаются, всегда пишут только корректный код, не допускают никаких UB, всегда фиксят все варнинги до последнего.

я чищу все варнинги, кроме - unused тра-та-та. и уровень варнингов - типа по максимуму..взял из текущего вот проекта..

-Wall -Wextra -pedantic -pedantic-errors -Wredundant-decls -Wcast-align -Wundef -Wfloat-equal -Wunreachable-code -Wmissing-include-dirs -Wnoexcept -Wpointer-arith -Wwrite-strings -Wlogical-op -Wlogical-not-parentheses -Wbool-compare -Wint-in-bool-context -Wmisleading-indentation -Wswitch -Wswitch-default -Wswitch-bool -Wnon-virtual-dtor -Wctor-dtor-privacy -Wdelete-non-virtual-dtor

а варнинги невозврата результата можно лифтить в ошибки. и все будет как у других.

alysnix ()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от den73

я не понимаю слово «безопасность», поэтому не могу определить ее уровень в c++.

  • что ее обеспечивает? язык, программист, третьи лица?
  • что значит идеальная безопасность? например только от ошибок работы с памятью какая-то страховка или вобще страховка от всех возможных ошибок?
  • как ее достичь? не любой способ достижения безопасности будет приемлем, например запрет на какое-либо действие не является способом достижения безопасности этого действия. или, например, слишком много бестолковых предупреждений скроют из внимания толковое. ну и в целом, если на этот вопрос нет ответа, то, возможно, цель не является достижимой
  • сколько ресурсов я готов потратить на ее достижение (как времени разработки так и времени выполнения)?
  • возможна ли ситуация, когда я хочу отказаться от этого? то есть то, что считалось безопасным почему-либо перестает меня устраивать и мне нужно нечто опасное?
  • возможно ли доказать, что, если я могу отказаться от безопасности, то это не поставит крест на всей остальной системе?

например я использую умные указатели. можно ли считать безопасностью потенциальную возможность петли, когда объект а ссылается на б а б ссылается на а и они никогда не удалятся?

zerhud ()
Ответ на: комментарий от archie

Отсутствие нормальной системы модулей. И нет, C++20 ни разу не панацея, никто старые кодовые базы на них переводить не будет, модули так и будут сосуществовать с инклудами в общей помойке.

Никто не будет отказываться от инклудов и переводить всё на модули (ну кроме энтузиастов, которые рано или поздно поймут тщетность этой затеи), ибо они позволяют делать трюки, которые модули не могут. Конечная либа будет оборачиваться в модуль и юзаться во внешнем коде решая всякие вопросы, например, с видимостью макросов или видимостью упомянутых внешних ворнингов.

По поводу центрального хранилища - после разговоров о закрытии гитхаба известно для кого, я сильно сомневаюсь в разумности чрезмерной централизации.

kvpfs ()
Ответ на: комментарий от X512

https://mesonbuild.com/Wrapdb-projects.html

Ничтожно малое число пакетов, даже двух сотен не набирается. Увы, ни в какое сравнение с crates.io и тем более npm это не идет. Малое количество пакетов - это кстати общая проблема всех попыток создать пакетный репозиторий для С++. А без большого количества пакетов никто этими репозиториями всерьез пользоваться не будет.

Meson

Всего лишь одна из многих систем сборок, причем довольно маргинальная и непопулярная. За пределами гномотусовки о мезоне никто и не слышал особо. Даже близко не стандарт типа Cargo, которым собираются абсолютно все пакеты в экосистеме. А жаль, Meson все же поприятнее, чем CMake.

archie ()
Ответ на: комментарий от archie

центральное хранилище - идея привлекательная только пока не захочешь выйти за рамки этой идеи. например, у меня в проекте генерится js клиент. плюс, в некоторых проектах, есть вбоще веб морда, можно на страницу подключить, там виджеты целые для настройки. cmake качает кое-какие js либы из сети, чтобы это работало. сомниваюсь, что они бы лежали в центральном хранилище.

вобще я юзаю nix. считаю что не должно быть никакого хранилища для языка, это слишком узко. вот то, что nix может мне собрать нужное окружение - это ценно. там могут быть как просто переменные окружения так и целые пакеты с чем угодно, начиная от плюсовых библиотек, кончая просто какими-то файлами. для вышегоуказанной задачи там есть путь ко всем нужным файлам, так что если собираюсь под nix то беру все от туда.

zerhud ()
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)