Здравствуйте, CreatorCray, Вы писали:
CC>Теперь твоя очередь объяснять как ты из моего фейспалма вытащил утверждение "UB — ерунда"
Экстраполяцией.
CC>Что именно ты тут понимаешь под "интовая арифметика"?
сложения, вычитания, умножения.
CC>метапрограммирование
CC>Вот только не надо забывать что compile-time вычисления работают НЕ по правилам платформы, под которую выполняется компиляция.
Хм. И в каком месте стандарта это разрешено?
Насколько я понимаю, всё поведение компилятора за пределами UB достаточно жёстко ограничено. Он не имеет права менять семантику программы, в том числе, и в целях оптимизации.
То есть если у меня описана какая-то формула, которая при "вычислении в рантайме" даёт X, то компилятор может перестраивать эту формулу ровно в тех пределах, в которых она при исполнении всё ещё даст X.
В том числе и выполнять часть вычислений в compile-time. Если на целевой платформе вычисления выполняются по-другому, то компилятор обязан проэмулировать именно их.
Особенности тут могут быть только вокруг плавающей точки, где поведение определяется флагами компилятора.
CC>То, что ты в данном примере называешь UB — на самом деле очень даже defined behavior. Неожиданный — да, но не undefined.
Простите, какой именно эффект? Вывод oops вместо wow? Нет, это именно что undefined behavior. Именно поэтому он зависит от флагов компиляции.
S>>S>>long avg(long a, long b, long c)
S>>{
S>> return (a+b+c)/3;
S>>}
S>>
CC>А что именно ты тут считаешь UB? Переполнение знакового типа имеет очень даже defined поведение для платформы, и если погромист не знает что творит — это недостаток квалификации.
Нет. Вы путаете implementation-defined и undefined behavior.
Если бы знаковое переполнение было implementation-defined, то ни с какими флагами компилятор бы не выдавал oops ни на какой платформе.
Однакож, он вполне успешно выдаёт oops на вполне известной платформе, нарушая ожидание.
Здесь, по стандарту, ровно два UB — в первом сложении и во втором.
Читаем стандарт:
If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined.
Эта клауза покрывает сложение с переполнением, вычитание с переполнением, умножение с переполнением, и деление на ноль.
CC>А у меня абсолютно везде беззнаковая, кроме тех редких мест где знак именно что нужен.
Ну,
у вас — может быть.
Поверю вам на слово.
Но в среднем такого нет. Язык настойчиво подталкивает программистов к знаковым операциям. Начиная прямо с
auto a = 42. Какого типа будет a? То-то же.
CC>Потому что "оптимизатор" по какой то внутренней причине ниасилил свернуть формулу в символьном виде, сработал fallback path и он формулу посчитал внутри себя на таких же типах, на том же железе.
Совершенно верно. Вот GCC осиливает свёртку (потому что у них внутри есть SCEV), и его не получается сбить с толку введением временной переменной.
Но это ровно противоположно тому, что вы писали в предыдущем сообщении.