LINUX.ORG.RU

юнионы в C++

 


2

4

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

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

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

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

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

★★★★★

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

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

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

Это ты так 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 ★★★
()
Ответ на: комментарий от alysnix

Даёшь политеизм строк!

den73 ★★★★★
() автор топика
Ответ на: комментарий от 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
()
Ответ на: комментарий от archie

Всего лишь одна из многих систем сборок, причем довольно маргинальная и непопулярная.

Meson появился недавно и стремительно набирает популярность.

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