LINUX.ORG.RU

LLVM. Зачем он вообще нужен?

 ,


3

6

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

Я не понимаю, почему не использовать просто компиляцию через Си или Си++. Оптимизации сделает компилятор Си. Семантика у LLVM всё равно совпадает с Си, по объёму кода компилятора тоже выигрыша практически нет. Зато если использовать Си, можно использовать любой из компиляторов Си и компилировать для платформ, для которых нет реализации LLVM.

★★★★★
Ответ на: комментарий от monk

И только. Причём этот пункт воткнут не из желания прописать семантику сложения в си, а с целью упрощения объяснения приведения типов и адресной арифметики дальше в тексте стандарта.

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

Но этот пункт всё-таки не даёт на 1 + 1 вернуть 3. Если у вас в стране не альтернативная математика.

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

Ты хочешь доказать, что в стандарте есть гарантии на результат матвыражений?

6.5.5

6
When integers are divided, the result of the / operator is the algebraic quotient with any
fractional part discarded.
If the quotient a/b is representable, the expression
(a/b)*b + a%b shall equal a; otherwise, the behavior of both a/b and a%b is
undefined.

Вот тебе два оператора, в отношении которого прямо сказано - «сделайте как хорошо, не получится? Ну, как сумеете.»

Фактически использование любого из этих операторов согласно тексту стандарта == UB.

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

Ты хочешь доказать, что в стандарте есть гарантии на результат матвыражений?

На некоторые есть.

Вот тебе два оператора, в отношении которого прямо сказано - «сделайте как хорошо, не получится? Ну, как сумеете.»

Нет. Тут всё однозначно. Результат «algebraic quotient with any fractional part discarded». Но результат может не попадать в нужный тип INT_MIN/(-1) например не «is representable», а значит UB.

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

Что именно в твоём понимании делает Brainfuck низкоуровневым?

Вот если бы ты про Форт спросил, то там бы можно было поспорить, хотя он тоже низкоуровневый. Но всё-таки там есть определённая мощь. А что спорить об языке, у которого маленький набор примитивных команд, оперирующих примитивными же данными (ячейками памяти)?

новые бессмысленные вопросы

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

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

Тут всё однозначно.

Ага. Пополняем список операторов, содержащих UB:

int add(int a, int b)
{
     return a + b;
}
int div(int a, int b)
{
     return a / b;
}
int reminder(int a, int b)
{
     return a % b;
}
int shift_left(int a, int b)
{
     return a << b;
}
int shift_right(int a, int b)
{
     return a >> b;
}
LamerOk ★★★★★
()
Ответ на: комментарий от nionio35

В других языках или всё отдаётся на волю операционной системы (ассемблер, форт, …) или происходит явная проверка (паскаль, лисп, …).

На самом деле, это сделано, как и любое UB, чтобы можно было выкидывать ненужные операции.

int data[10];

int test2(int n)
{
  if(n < 20) return 1; else return 2;
}

int test(int n)
{
  if(data[n] > 0 && test2(n) < 2) return 1;
  return 0;
}

Здесь функция test оптимизируется до

int test(int n)
{
  if(data[n] > 0) return 1;
  return 0;
}

потому что, если мы смогли прочитать data[n], значит 0 <= n < 10 и test2(n) всегда равен 1.

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

На самом деле, это сделано, как и любое UB, чтобы можно было выкидывать ненужные операции.

При UB «нужность» операции теряет смысл, теряет семантическое значение: можно удалять, дополнять, заменять - семантика программы на СИ не изменится.

Поэтому твою «программу с UB» gcc компилирует по разному:

  • при -O0 - как ожидает человек, не заметивший UB
  • при -O1 - как ожидает человек, заметивший UB
  • при -02 и выше - как не ожидает человек
anonymous
()
Ответ на: комментарий от monk

Пополняем список операторов, содержащих UB

… при некоторых значениях аргументов.

Ты берёшься формально доказать в отдельно взятом юните трансляции, что аргументы укладываются в допустимые диапазоны? Потому что если нет - то это UB. Прямое, простое и бесхитростное, прямо прописанное в стандарте.

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

Ты берёшься формально доказать в отдельно взятом юните трансляции, что аргументы укладываются в допустимые диапазоны?

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

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

не выходит за массив, значит всегда там 1. а если 0 > n >= 10 так ты хочешь прочитать то что нельзя.

Да, но нет. В оптимизаторе НЕТ той логики, что monk пытается изложить и ты видишь. Оптимизатор просто попытался вычислить в константные значения отдельные ветки кода. На более крупной цепочке более сложных вызовов та же самая оптимизация может не сработать. У тебя нет гарантии, что компилятор по коду везде сделает такие замены.

Повторюсь (раз тред никто не читает), это не семантика языка программирования, это эвристика оптимизации конкретного компилятора.

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

аргументы укладываются в допустимые диапазоны? Потому что если нет - то это UB

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

Иначе все прогаммы - UB и форматируют диск

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

Именно это ожидается от ответственного программиста.

И ты, конечно же, можешь привести в пример хоть один реальный программный продукт с доступным кодом, где мы можем это увидеть на каждой операции?

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

У тебя нет гарантии, что компилятор по коду везде сделает такие замены.

Так нет гарантии, что оптимизация вообще хоть какая-то будет. Оптимизация может быть, а не обязана быть.

это не семантика языка программирования, это эвристика оптимизации конкретного компилятора

Это как раз семантика. Вот такая же семантика, привязанная к конкретной функции, а не набору UB: https://doc.rust-lang.org/std/hint/fn.unreachable_unchecked.html

if (x > 0) { f(x); } else { std::hint::unreachable_unchecked(); } 

компилятор вправе сократить до вызова f(x) и внутри функции быть уверенным, что x положительный.

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

Так нет гарантии, что оптимизация вообще хоть какая-то будет. Оптимизация может быть, а не обязана быть.
Это как раз семантика.

Ты сам себя не пробовал прочитать? Что это за «семантика» языка программирования, которая может быть, а может и не быть? Это семантика мигалки, чтоле?

компилятор вправе

Не-не-не, девид блейн. Ты сейчас притащил натуральную #pragma unreachable из вообще другого языка программирования в доказательства своего тезиса о Си. Это так не работает.

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

Так любой достаточно старый, какой ни возьми.

Например, https://github.com/torvalds/linux/blob/master/crypto/aead.c#L272

Программист проанализировал, что count при вызове точно не равен INT_MIN, а значит UB в этом арифметическом действии не происходит.

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

Что это за «семантика» языка программирования, которая может быть, а может и не быть?

Нормальная семантика. В лиспе такое тоже есть.

(eq 3.0 3.0)
=>  true
OR=>  false

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

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

x передается по значению или по ссылке?

Есть разница?

если в другом потоке значение x меняется?

В случае rust то, что может поменяться в другом потоке, нельзя сравнить с нулём.

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

Нормальная семантика.

Приехали.

В лиспе

Это многое объясняет. Давай-ка я в рамках гуманитарной помощи лисп-сообществу помогу тебе сформулировать твой тезис и озвучу свой контр-тезис.

Эта ветка срача началась с

Есть UB не от платформы.

После двух увлекательных дней, мы можем, наконец-то, озвучить твой тезис полностью:

Ты утверждаешь, что некоторое UB, позволяющее компилятору модифицировать целевую программу, является частью семантики языка си.

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

Предлагаю тебе переформулировать твой тезис и/или оспорить мой.

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

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

Если бы это было так, то всё, что не описано в стандарте любого языка, позволяло бы компилятору переписывать программу. Или в том же Си оптимизатор мог бы выкидывать не только явно указанный UB, но и, например, ветки с опечатками в ключевых словах (это же тоже не указано в стандарте).

Или можно было бы написать компилятор лиспа, соответствующий стандарту, с аналогичной семантикой доступа к элементам массива, как в Си. Ведь тут не указано, что может быть, если индекс за пределами массива: https://www.lispworks.com/documentation/HyperSpec/Body/f_aref.htm

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

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

Пчёл, у нас не лисп!!!111 Опечатки в ключевых словах - это синтаксически не корректная конструкция, она до оптимизатора просто не доходит.

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

Именно это мы и наблюдаем с оптимизациями при UB: раз, два.

В Си UB явно указано в стандарте.

А где последствия UB указаны в стандарте?

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

Именно это мы и наблюдаем с оптимизациями при UB: раз, два.

Это в Си/Си++. А я про то, что если бы было так, то такое встречалось бы в любом языке, на который есть стандарт. Например, в ECMAScript.

Опечатки в ключевых словах - это синтаксически не корректная конструкция, она до оптимизатора просто не доходит.

До компилятора же доходит. И в стандарте не описано, что должно при этом происходить.

А где последствия UB указаны в стандарте?

Permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).

Вот оптимизирующие компиляторы и «behaving during translation … in a documented manner characteristic of the environment».

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

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

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

Ты явно стандарт не читал. 4-ая глава:

5
A strictly conforming program shall use only those features of the language and library
specified in this International Standard.3) It shall not produce output dependent on any
unspecified, undefined, or implementation-defined behavior, and shall not exceed any
minimum implementation limit.

Как только компилятор в ходе трансформации кода встретил UB и не прервал компиляцию, а продолжил работу - результат его работы не соответствует стандарту языка. Хуже того, даже если нигде в ходе компиляции не встретилось 100%-ого UB, то результирующая программа всё равно еще не корректна:

3
A program that is correct in all other aspects, operating on correct data, containing
unspecified behavior shall be a correct program and act in accordance with 5.1.2.3.

То есть программа на сишечке корректна, только пока пользователь вводит правильные данные. Ошибся в воде - все взятки гладки.

behaving during translation … in a documented manner characteristic of the environment

И это не является семантикой самого языка программирования си так, как он определён в стандарте. Это уже семантика environment’а, компилятора, программы КПСС, чего угодно - но не языка программирования си.

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

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

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

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

Лол, нет, это так не работает. Если в ПДД написано:

23.5. Движение тяжеловесного и (или) крупногабаритного транспортного средства, а также транспортного средства, осуществляющего перевозки опасных грузов, осуществляется с учетом требований Федерального закона "Об автомобильных дорогах и о дорожной деятельности в Российской Федерации и о внесении изменений в отдельные законодательные акты Российской Федерации".

Международные автомобильные перевозки осуществляются в соответствии с требованиями к транспортным средствам и правилами перевозки, установленными международными договорами Российской Федерации.

Это не значит, что ФЗ о дорогах и договора являются частью ПДД. ПДД и эти законы и договора сосуществуют параллельно. Семантика конкретно ПДД ограничена самими ПДД.

Ну и прямой запрет на использование UB в стандарте:

It shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior

ты чем будешь крыть?

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

Это не значит, что ФЗ о дорогах и договора являются частью ПДД.

Вот в этом у нас и есть разногласия. Я считаю, что в семантику (то есть смысл) ПДД входит, в том числе, и семантика упомянутого ФЗ. Потому что если этот ФЗ будет нарушен, это будет трактоваться как нарушение ПДД (п.23.5).

It shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior

Это ограничение подкласса программ «strictly conforming program». Если в программе нет «output dependent on any unspecified, undefined, or implementation-defined behavior», то, очевидно, эта программа будет возвращать одинаковые результаты, будучи скомпилированной любым компилятором, соответствующим Стандарту.

Но это не ограничение на действия компилятора.

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

Потому что если этот ФЗ будет нарушен, это будет трактоваться как нарушение ПДД (п.23.5).

А вот и нет. Порядок ответственности за нарушение ФЗ указан в самом ФЗ:

Глава 10. Ответственность за нарушение законодательства Российской Федерации об автомобильных дорогах и о дорожной деятельности

Статья 46. Ответственность за нарушение законодательства Российской Федерации об автомобильных дорогах и о дорожной деятельности

1. В случаях и в порядке, которые установлены законодательством Российской Федерации, лица, нарушившие законодательство Российской Федерации об автомобильных дорогах и о дорожной деятельности, несут гражданско-правовую, административную, уголовную и иную ответственность в соответствии с законодательством Российской Федерации.

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

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

It shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior

Это ограничение подкласса программ
Но это не ограничение на действия компилятора.

Нет. За produce отвечает компилятор, и это именно ограничение на компилятор.

Ограничения на исполнение программ в стандарте вообще нет вот по этой причине:

5. Environment
1
An implementation translates C source files and executes C programs in two data-
processing-system environments, which will be called the translation environment and
the execution environment in this International Standard. Their characteristics define and
constrain the results of executing conforming C programs constructed according to the
syntactic and semantic rules for conforming implementations.

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

Their characteristics define and constrain the results of executing conforming C programs

Т.е. результат вычисления программы не определяется стандартом языка, а полностью зависит от вычислителя (о чём я уже говорил).

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

Кмк тут решает декомпозиция и отвязка от неконтролируемого и относительно раздутого стандарта Си, ибо если взять Си в качестве IR, то получаем - сложный язык, вопросы по стандарту(напр. какой выбрать, что делать с UB и пр.), своеобразность рантайма и виртуальной машины Си(собсна IR и вводят для соответствия конкретной ВМ с конкретными свойствами). Касательно декомпозиции - очевидно можно по честному отвязать фронд от бэка и развивать их независимо(по сути это сильно упрощает разработку), плюс есть нюансы связанные с трансляцией в Си - по сути переносимость Си ограниченная и IR должен позволять делать те вещи, которые в Си нельзя сделать явным образом без использования ассемблера. Предположу что решающими факторами являются именно стоимость поддержки и эволюции, ибо IR сделанный конкретным и определённым это явная возможность разделить разработку на llvm и отдельные фронты уровня clang. Плюс вопрос на подумать - будет ли просто конвертить через си-IR транслировать код например с C23 в С89/С99(потенциальные варианты IR). В остальном как вариант можно было не на лоре спрашивать, а у разрабов напрямую, кто-то да ответит.

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

В остальном как вариант можно было не на лоре спрашивать, а у разрабов напрямую. К каким разрабам ? Исходник собран инопланетным образом с тремя нолями. Ну иди поищи по галактеке исходник

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

То есть программа на сишечке корректна, только пока пользователь вводит правильные данные. Ошибся в воде - все взятки гладки.

Вы уволены.

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

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

хоть для приличия открыл ФЗ - там, например, прописаны виды собственности на дороги

осуществляется с учетом требований Федерального закона "Об автомобильных дорогах и о дорожной деятельности в Российской Федерации и о внесении изменений в отдельные законодательные акты Российской Федерации"

Вот нарушен этот ФЗ, судья пишет «…водитель, управляя транспортным средством (в составе автопоезда) марки <данные изъяты> в нарушение п. 23.5 ПДД РФ,…» (https://sudact.ru/regular/doc/JKoBFMjjuKb8/)

Нет. За produce отвечает компилятор, и это именно ограничение на компилятор.

В цитате «It shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior» It = «strictly conforming program». Так Вы считаете, что это компилятор должен быть «strictly conforming program»?

Their characteristics define and constrain the results of executing conforming C programs

Вы же сами пишете «constructed according to the syntactic and semantic rules for conforming implementations». Цвет автомобиля Форд-Т может быть любым, если этот цвет чёрный. Результат вычисления может быть любым, соответствующим синтаксису и семантике соответствующей стандарту реализации компилятора.

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

вопросы по стандарту(напр. какой выбрать, что делать с UB и пр.)

Определённо, в скомпилированной в Си программе UB быть не должно, если его нет в исходной программе.

своеобразность рантайма и виртуальной машины Си

Так при первом же вызове функции ОС (а это почти всё, начиная с ввода-вывода) воткнёшься в рантайм и виртуальную машину Си. Разве что ОС совсем не POSIX, не на Си или Си++, но на чём-то основанном на LLVM (такие вообще существуют?).

IR должен позволять делать те вещи, которые в Си нельзя сделать явным образом без использования ассемблера

Так их и в LLVM обычно нельзя сделать.

ибо IR сделанный конкретным и определённым это явная возможность разделить разработку на llvm и отдельные фронты уровня clang

Выше указали, что основная причина экономическая: можно сделать свой закрытый компилятор из llvm для своего процессора, интегрировать с clang и продавать в закрытом виде. Это намного проще, чем писать компилятор современного Си++.

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

Порядок ответственности за нарушение ФЗ указан в самом ФЗ:

Вот нарушен этот ФЗ, судья пишет

Ты, если не понимаешь каких-то формулировок, лучше спрашивай. Потому что по твоей же ссылке:

о привлечении к административной ответственности по ч. 2 ст. 12.21.1 КоАП РФ,

КоАП - это не ПДД. ПДД - не КоАП. Водилу привлекли за нарушение ФЗ по КоАП.

Так Вы считаете, что это компилятор должен быть «strictly conforming program»?

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

Теперь ещё раз медленно и печально: поведение соответствующей стандарту программы не может зависеть от UB. То есть, компилятор не может генерировать код на основании обнаруженного UB.

Вот к примеру эта программа содержит UB:

#include <limits.h>
int main(void) { return INT_MAX +1; }

Если компилятор определил наличие UB, он должен либо прекратить трансляцию юнита, либо то, что он выдаст заведомо не будет strictly conforming program.

Вы же сами пишете «constructed according to the syntactic and semantic rules for conforming implementations». Цвет автомобиля Форд-Т может быть любым, если этот цвет чёрный.

Это потому что ты стандарт за эту неделю так и не осилил прочитать. Если бы прочитал, то знал, что semantic rules в сишечке описаны через некоторые свойства execution environment. Вот к примеру:

3.5
1
bit
unit of data storage in the execution environment large enough to hold an object that may
have one of two values
2
NOTE 
It need not be possible to express the address of each individual bit of an object.
3.6
1
byte
addressable unit of data storage large enough to hold any member of the basic character
set of the execution environment
...
6.2.5 Types
...
5
An object declared as type signed char occupies the same amount of storage as a
‘‘plain’’ char object. A ‘‘plain’’ int object has the natural size suggested by the
architecture of the execution environment (large enough to contain any value in the range
INT_MIN to INT_MAX as defined in the header <limits.h>).

А в отношении самого execution environment (за вычетом API и библиотек) есть лишь ограниченный набор требований на запуск и останов программы. То есть сами детали вычислений в стандарте не описаны, в стандарте описано, как сишный код должен транслироваться в формально неописанный и толком неизвестный execution environment.

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

КоАП - это не ПДД. ПДД - не КоАП.

КоАП определяет наказание. ПДД указывает, что нельзя нарушать. Не путайте. Здесь же написано

привлечена к административной ответственности по ч.2 ст. 12.21.1 КоАП РФ и назначено наказание в виде штрафа в сумме 300 000 руб. за то, что ДД.ММ.ГГГГ в <адрес> водитель, управляя транспортным средством (в составе автопоезда) марки <данные изъяты> в нарушение п. 23.5 ПДД РФ

Если компилятор определил наличие UB, он должен либо прекратить трансляцию юнита, либо то, что он выдаст заведомо не будет strictly conforming program.

Разумеется. И даже если не определил, но оно есть в тексте программы.

Если бы прочитал, то знал, что semantic rules в сишечке описаны через некоторые свойства execution environment.

Общение чем дальше, тем больше уходит в философию. «Вот эта лошадь где? Она перед тобой или в твоей голове?». Вот и семантические правила соответствующей Стандарту реализации языка Си внезапно оказываются в среде исполнения, в которой запущена скомпилированная этим компилятором программа.

Вы специально уходите в софистику или действительно пытаетесь доказать, что даже строго соответствующая Стандарту (strictly conforming) программа на Си может выдавать разные результаты в разных средах исполнения?

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

КоАП определяет наказание. ПДД указывает, что нельзя нарушать. Не путайте.

Это ты сейчас заявил, что КоАП не содержит статей о том, что нельзя нарушать? И без ПДД водилу нельзя привлечь к ответственности? Ты не пробовал перед тем, как писать что-то в интернете, сначала прочитать в нём что-то?

И даже если не определил, но оно есть в тексте программы.

Ты сегодня с помехлюги, чтоли? Как программа может выполнить действие на основании условия, которого она не смогла определить?

действительно пытаетесь доказать, что даже строго соответствующая Стандарту (strictly conforming) программа на Си может выдавать разные результаты в разных средах исполнения?

Чувак, значение любого арифметического выражения с типами float или double совершенно не известно. И да, на разном оборудовании оно будет выдавать разные результаты. Это азы двоичной арифметики.

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

И без ПДД водилу нельзя привлечь к ответственности?

Да. Потому что в нём указаны те нормы, за нарушение которых по КоАП предусмотрена ответственность.

Как программа может выполнить действие на основании условия, которого она не смогла определить?

Например, если компилятор переводит a[i] в mov r1, [a+i] без какого-либо контроля допустимости указателя, а при выполнении a+i оказалось за пределами массива.

Чувак, значение любого арифметического выражения с типами float или double совершенно не известно.

F.2 Types 

The C floating types match the IEC 60559 formats as follows: 
— The float type matches the IEC 60559 binary32 format. 
— The double type matches the IEC 60559 binary64 format. 
monk ★★★★★
() автор топика
Ответ на: комментарий от monk

И без ПДД водилу нельзя привлечь к ответственности?

Да.

Ладно, дальнейшую дискуссию о КоАП я предаю в надёжные руки сотрудников ППС и дежурного в отделении. Для этого срача это уже через чур.

при выполнении a+i оказалось за пределами массива.

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

Чувак, значение любого арифметического выражения с типами float или double совершенно не известно.

Как красиво ты вырезал кусочек! Прям загляденье. А текст до и после почему пропал?

F.1 Introduction
1
This annex specifies C language support for the IEC 60559 floating-point standard. 
... An implementation that
defines _ _STDC_IEC_559_ _ shall conform to the specifications in this annex.356)

F.2 Types 

The C floating types match the IEC 60559 formats as follows: 
— The float type matches the IEC 60559 binary32 format. 
— The double type matches the IEC 60559 binary64 format. 
— The long double type matches an IEC 60559 extended format,357) else a
non-IEC 60559 extended format, else the IEC 60559 double format.

А теперь вслух и с выражением читаем ссылку мелким шрифтом:

356) Implementations that do not define _ _STDC_IEC_559_ _ are not required to conform to these
specifications.

Ссылку, я так чувствую, поставили специально для тебя. ))

В 88/89 стандарте вообще ничего про IEEE 754 и производные нет.

Ну и наконец, тривиальный же пример, без единой арифметической операции:

user@computer:/tmp$ cat size_t_size.c 
#include <stdio.h>

int main(void)
{
    (void) printf("%zu\n", sizeof(size_t));
    return 0;
}
user@computer:/tmp$ gcc -m32 -pedantic -Wall -Wextra -o size_t_size size_t_size.c 
user@computer:/tmp$ ./size_t_size 
4
user@computer:/tmp$ gcc -pedantic -Wall -Wextra -o size_t_size size_t_size.c 
user@computer:/tmp$ ./size_t_size 
8
user@computer:/tmp$ 

Предлагаю тебе найти несоответствие программы стандарту и/или доказать, что 8 == 4.

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

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

Никак. Я же именно это и утверждаю. Компилятор определить UB не может, но оно есть, а значит программа не strictly conforming.

Предлагаю тебе найти несоответствие программы стандарту и/или доказать, что 8 == 4.

sizeof(size_t) является implementation-defined behavior.

are not required to conform to these specifications.

Убедил. Любая программа, использующая вещественные числа, не strictly conforming.

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

sizeof(size_t) является implementation-defined behavior.

Ровно в том же смысле, что и диапазоны значений int или unsigned long int. Вот мы и пришли к тому - с чего начали: стандарт позволяет одной и той же программе, полностью ему соответствующей и даже не имеющей никакого UB, выдавать разные численные результаты

Поскольку, теперь мы твёрдо установили, что strictly conforming программа не может сделать сильно большего, чем сложить два плюс два, а вся арифметика у нас - это сплошной implementation-defined, который никак не documented manner characteristic of the environment, то предлагаю тебе теперь с учётом этого факта, попробовать доказать свой тезис:

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

тк по твоим словам:

В Си UB явно указано в стандарте.

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

Ровно в том же смысле, что и диапазоны значений int или unsigned long int.

Про это есть специальная оговорка «shall not exceed any minimum implementation limit». То есть

#include <stdio.h>

int main(void)
{
    int x = 20;
    int y = 22;
    (void) printf("%d\n", x + y);
    return 0;
}

является strictly conforming, так как значения не выходят за минимальные пределы, определённые Стандартом.

предлагаю тебе теперь с учётом этого факта, попробовать доказать свой тезис

Я пропустил какой-то пункт твоего доказательства. Да, программы соответствующая Стандарту, но не строго соответствующая, может возвращать разный (зависящий от реализации) результат, если использует конструкции, зависящие от реализации. Но возможность трактовать UB как «то, чего не может быть» есть только благодаря тому, что в стандарте в явном виде оно описано.

Если бы вместо UB всюду было Implementation-defined behavior или даже Unspecified behavior, то большая часть основанных на UB оптимизаций была бы невозможна.

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

Я пропустил какой-то пункт твоего доказательства.

Ты его просто не понял, а я проморгал твоё отрицание.

Про это есть специальная оговорка «shall not exceed any minimum implementation limit».

Ты покажешь, в каком месте программа:

#include <stdio.h>

int main(void)
{
    (void) printf("%zu\n", sizeof(size_t));
    return 0;
}

«exceed any minimum implementation limit» ? Потому что, если не покажешь, это - strictly conforming.

Отрицание, которое я пропустил:

Любая программа, использующая вещественные числа, не strictly conforming.

Это в общем случае не верный тезис. Программа может использовать типы с плавающей точку и быть strictly conforming:

#include <stdio.h>

int main(void)
{
    double d = 1.1;
    (void) printf("%f\n", d);
    return 0;
}

Числовые лимиты нигде не превышены, используется только стандартная библиотека, нет UB == strictly conforming.

Ещё раз медленно и очень очень печально: программа полностью строго соответствующая стандарту, может возвращать разный (зависящий от реализации) результат.

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

И ты, конечно же, можешь привести в пример хоть один реальный программный продукт с доступным кодом, где мы можем это увидеть на каждой операции?

Линуксовое ядро. Все входящие от userspace параметры проверяются на соответствие диапазонам. Внутри ядра понатыканы проверки в духе «если вот эта шляпа больше допустимого значения верни ошибку». У тебя в общем-то правильно в нике про ламера написано, очень похоже.

anonymous
()