Суть примера 3 не в том, что в программе строки 2 Gb и по ним циклами бегают. Хотите я вам аналогичный пример приведу где размер матрицы вычисляется в int?
Суть примера 6 не в том, как вывести строку в обратном порядке, а в типовых граблях циклов с беззнаковым счётчиком.
Комментарии не читай @ сразу отвечай. Все примеры взяты из реальных программ, но упрощены, потому что с огромными листингами никто бы не возился.
7. В любом коде на Си есть приведения типов указателей. Кто даст гарантию, что они корректны? И далеко не всем очевидно, что так делать нельзя. И не обязательно передавать указатели вот так явно в функцию, их можно доставать из структур данных или ещё как-то.
Да сколько можно. Это минимальные wtf-примеры. Все примеры взяты из реальных программ, просто уменьшены, сложные типы заменены на встроенные и так далее, поэтому конкретно такой код кажется ненастоящим. Но настоящий код просто нельзя поместить в статью — никто с этими огромными листингами бы не разбирался.
Оптимизатор не обязан это делать. Хорошо что в данном случае это выражение соптимизировалось в clang, у которого есть AST с выражениями и номерами строк. Но если какое-то другое выражение сворачивается на уровне LLVM (например, посмотрите вот этот доклад www.youtube.com/watch?v=r3ic-IHJTuA&list=PL970A5BD02C11F80C&index=12&feature=plpp_video и какие выражения LLVM вскоре будет уметь сворачивать) то на уровне LLVM даже может не быть нужной информации о строках. Или хуже того, такое выражение появится в результате двух уровней инлайнинга и трёх шагов раскрутки цикла: просто нет такой одной строки, где это выражение записал программист.
> UB должно относиться только к тому выражению, где оно используется
UB относится ко всему выполнению программы, где имеется UB. Не гарантируется даже что действия до UB будут выполнены корректно. Вся программа с UB не имеет смысла.
Потому что когда система спускается сверху, она никому не нужна: вверху её никто не хочет наполнять так как у них и так куча отчётности и прочих бумажек, внизу ей не будут пользоваться потому что при проектировании явно будет забыто что-то критичное. А когда я сделал форум и постоянно обеспечиваю наличие там актуальной информации, то я удовлетоврил настоящую потребность и в том виде, в котором это было необходимо (и с удивлением недавно обнаружил как другие потоки используют «почтовый ящик группы» или социальные сети).
Такая система пишется каждый год кем-то в качестве диплома. А потом заваливается внедрение, потому что «да мы без вашей системы 30 лет работаем и ещё столько же проработаем».
Спасибо Кеп, я этот комментарий пишу с ARM ноутбука.
> во-2, на современном процесоре писать руками код, лучше чем тот, который сгерерирует компилятор нецелесообразно по времени
inline функция c одной командой add в inline asm. Я вам не предлагаю переписать весь код на asm, я вам предлагаю показать в коде явно какая семантика вам нужна вместо того, чтобы надеяться на непонятно что.
Это не сферические примеры. Это настоящий пример, в котором программист рассчитывал, что раз сложение реализуется командой add, то и переполнение в Си будет такое же. Пишете эмулятор и нужно переполнение чисел со знаком mod 2^n — напишите inline asm.
Это вполне конкретный пример (определения того, а не произойдёт ли переполнение при инкременте), который был написан для twos complement машин и работал до тех пор, пока его не скомпилировали с оптимизатором, который пользуется правом, данным ему по стандарту.
А теперь я вам говорю, что компилятор имеет право (и clang, например, пользуется этим правом) сказать что (x+1)<x всегда false, потому что или это false по стандарту или тут undefined behavior и тут false потому что clang'у так хочется.
Суть примера 3 не в том, что в программе строки 2 Gb и по ним циклами бегают. Хотите я вам аналогичный пример приведу где размер матрицы вычисляется в int?
Суть примера 6 не в том, как вывести строку в обратном порядке, а в типовых граблях циклов с беззнаковым счётчиком.
7. В любом коде на Си есть приведения типов указателей. Кто даст гарантию, что они корректны? И далеко не всем очевидно, что так делать нельзя. И не обязательно передавать указатели вот так явно в функцию, их можно доставать из структур данных или ещё как-то.
Я имел ввиду алгебру. В алгебре это действительно равно.
UB относится ко всему выполнению программы, где имеется UB. Не гарантируется даже что действия до UB будут выполнены корректно. Вся программа с UB не имеет смысла.
Скомпилируйте clang -ftrapv и запустите.
> во-1 кроме x86 есть и другие архитектуры
Спасибо Кеп, я этот комментарий пишу с ARM ноутбука.
> во-2, на современном процесоре писать руками код, лучше чем тот, который сгерерирует компилятор нецелесообразно по времени
inline функция c одной командой add в inline asm. Я вам не предлагаю переписать весь код на asm, я вам предлагаю показать в коде явно какая семантика вам нужна вместо того, чтобы надеяться на непонятно что.