не нравятся и эти вещи описываются стандартом как "неопределенное поведение" или "не опрелелено" или "не разрешено". Например мне не нравится отсутствие гарантии последовательного выполнения аргументов. Но стандарт это не язык - это способ разработчиков компиляторов договориться о неком подмножестве языковых нюансов чтобы код выполнялся одинакво при замене одного компилятора на другой.
Но ведь не всем юзерам важна возможность замены компилятора. Меня например интересует только clang которого я буду использовать как библиотеку (то есть работать с его внутренним апи) для сборки проекта чтобы например реализовать горячую перезагрузку и некую обработку аст при сборке.
И поскольку проект уже будет завязываться на конкретный компилятор и более того на конкретную версию компилятора то появляется желание не ограничиваться стандартом а использовать конкретное поведение конкретной версии компилятора и таким образом многие UB перестают быть UB и будут иметь конкретное поведение.
И появляется вопрос - а можно ли дальше решить некоторые недостатки плюсов вроде того же неопределенного порядка выполнения аргументов или строго порядка designated initializers? Алгоритм будет примено такой
1) если сам стандарт не разрешает или не определяет нужное поведение то может это разрешает и четко определяет сам компилятор?
2) если нет то может есть некоторые расширения языка у самого компилятора которые решат данную проблему?
3) если нет то может у компилятора есть настройки (флаги командной строки) которые позволяют это поменять?
4) если нет то может есть нужные флаги при сборке исходников самого компилятора?
5) если нет то может есть настроки у внутренней апишки компилятора? Вполне возможно что например внутренний апи clang-а или gcc намного богаче и мы можем решить нашу проблему просто используя компилятор как библиотеку при сборке проекта
6) если нет настроек у апишки самого компилятора то может можно написать модуль/плагин/хуки которые позволят поменять нужное поведение?
7) ну наконец если нет нет возможностей повлиять на это извне то может оказаться что достаточно поменять одну или несколько строчек в исходниках компилятора ну а поскольку компилятор будет использоваться как библиотека (для сборки и себя и проекта) то не будет никаких проблем заинклудить исходники компилятора в проект и получить детерминированную сборку на всех платформах
какое конкретно поведение вам так сильно не нравится, что аж заложиться на компилятор и флагами обложиться лучше чем учитывать что так нельзя делать?
Ок, а если меня интересует только конкретная процессорная архитектура в которую будет происходить компиляция (допустим я пишу серверные приложения которые будут выполняться на конкретных интел-железках) то тогда можно сказать что многие undefined behavior перестают быть таковыми? Допустим меня интересует только x64 c конкретным instructions set (например только avx/avx2 или sse/sse2 но точно без старья вроде x87 и mmx)
Какие "многие"?
никогда уб не перестаёт быть уб
Ну например моменты связанные с переполнением
Не то чтобы это могло помешать компилятору увидев уб вам что то странное нагенерить
Не имеет значения. Простой пример: под intel x86 сложение знаковых скорее всего скомпилируется во wrapping версию, но это не означает, что поведение стало defined - компилятор может делать предположение, что знакового переполнения не происходит.
например вы можете заложиться на атомарность чтения не атомарной переменной на конкретной архитектуре, но т.к. это уб (при конкурентной записи) это всё равно может превратиться в спецэффекты какие-то
Нет, не перестанут. Во-первых, это формальное, почти юридическое понятие, относящееся к C++. Вы либо пишите на C++, либо закладываетесь на конкретный набор условий – это уже будет какой-то ваш язык Во-вторых, если вам не представлено дополнительных гарантий, вы не можете заложиться только на одну конкретную процессорную архитектуру. Вы так же должны будете заложиться на фазу Луны, погоду на Марсе, геополитическую обстановки на спутниках Сатурна, а также на квантовую запутанность этой и других вселенных
Ну вот мне сильно не нравится неопределенный порядок выполнения аргументов - во всех остальных популярных языках порядок аргументов четко последователен а в с++ вдруг нет. Или например мне не нравится строгий порядок (согласно объявленю) полей в designated initalizers и хочется как-то это поменять пусть с завязкой на конкретный компилятор. В принципе это можно решить трансформацией аст перед компиляцией но это запасной вариант - хотелось бы решить с помощью встроенных средств вроде языковых расширений самого компилятора или возможностей api/плагинов/хуков
А ещё можно решать проблемы (например, порядка) с помощью IDE - сортировать самому в полуавтоматическом режиме
>> Или например мне не нравится строгий порядок (согласно объявленю) полей в designated initalizers и хочется как-то это поменять пусть с завязкой на конкретный компилятор И получить определённое, но нежелательное поведение, связанное с порядком вызова деструкторов?
Ок, я понимаю что поведение многих UB зависит от множества различных оптимизаций компилятора. Но если я использую компилятор как библиотеку и завязываюсь на конкретную версию то я же могу провести процесс максимально тонкой настройки компилятора. Я еще не разобрался но уверен что помимо общей настройки уровня оптимизации O0-O3 наверняка у компилятора можно тонко сконфигурировать какие конкретно оптимизации (из сотни или сколько их там) применяет тот же кланг (а потом и llvm) и даже настройки отдельных оптимизаций. Если разобраться во всем этом и настроить их все то можно сказать что мы решили еще какой-то список UB ?
Вы хотите разложить себе грабли.
Как можно наступить на грабли, если ноги уже отстрелены)
Вы не понимаете, это не дополнительные грабли или желание на них наступить - это наоборот желание решить две главные проблемы языка С++ - 1) сложность языка 2) большое количество UB. Первую проблему можно решить линтером и анализом аст где мы можно четко указать какие синтаксически конструкции и фичи мы будем использовать а какие нет и в итоге язык с++ превращается в небольшое подмножество синтаксических конструкций и фич которые намного проще изучить новичкам приходящим в проект. Ну а вторую проблему я хочу решить как раз таки использованием конкретного компилятора, его версии, максимально тонкой настойкой и явным обозначением платформы и ее особенностей в которую будет компилироваться проект. В конце концов язык это всего лишь инструмент так почему бы не использовать возможности этого инструмента для того чтобы упростить себе жизнь? Другие разработчики которые придерживаются подхода "язык это инструмент" как только сталкиваются с какими-то недостатками "стандартного" c++ то особо не разбираются и сразу переключаются на другие языки (и далеко не факт что в других языках не найдется куча своих нюансов и недостатков). Еще хуже когда в проект начинают тащить несколько языков. Ну а я всего лишь хочу использовать язык c++ или точнее компилятор языка с++ как инструмент чтобы решить те или иные задачи
Вы не решаете проблем, вы создаете проблемы себе.
ограничение подмножества языка может впринципе проводиться в автоматическом режиме либо на ревью, "большое количество уб" по моему преувеличенная проблема, (ваши усилия по её решению неадекватны по сравнению с размером проблемы)
Если c++ - сложный для Вас, есть альтернативы в виде других ЯП.
Так вычисли аргументы до вызова функции, явно в желаемом тобой порядке. Всё проблемы будут сняты.
Ты пишешь просто какую-то ерунду, если кратко...
strict aliasing передает привет
Обсуждают сегодня