известным компилем возвращает 42 т.к. использование неинициализированной переменной уб, но gcc при отсутствие флагов компиляции возвращает случайное значение и только при -О2 возвращает 42. Значит ли это, что некоторые уб gcc использует только для оптимизации?
#include <iostream>
int foo(bool c) {
int x, y;
y = c ? x : 42;
return y;
}
int main() {
std::cout << foo(true) << std::endl;
}
автор видео наверняка этот пример и привёл, чтобы показать что компиляторы могут оптимизировать уб
Он не уб использует а правила языка
Может кто-то объяснить, почему 42? Ведь в функцию передается истина, и нужно вернуть значение x, которое может быть чем угодно.
Андефайнед бехевиор, мы пытаемся присвоить значение ещё не инициализированной переменной другой переменной
42 это тоже что угодно
Ты в одном видео увидел бред. Тут ub, x не инициализирован.
Особенно от тебя это символично слышать...
у тебя какие-то проблемы ?
не сказал бы, что бред, но однозначно UB
Не ты не понял, я положительном смысле...
теперь я два раза не понял
Ильюха - человек-загадка
Ну вы же мыши, мыши и задавали Великий Вопрос... Точнее, для нас они были мышами.
мыши были заказчиками этого проекта
Все уб используются для оптимизаций
В функцию не может быть передан true никак, компилятор это понимает
почему не может ? компилятор выкидывает дифференциацию результата, а не ветвление по аргументу
В данном случае никакого ветвления не будет, c is always false => код схлопывается в return 42
мне кажется, это не совсем так ;; Function foo (_Z3foob, funcdef_no=1741, decl_uid=43349, cgraph_uid=508, symbol_order=541) Removing basic block 4 foo (bool c) { int y; int x; int iftmp.0_5; <bb 2> : # DEBUG BEGIN_STMT # DEBUG BEGIN_STMT if (c_2(D) != 0) goto <bb 3>; [INV] else goto <bb 4>; [INV] <bb 3> : iftmp.0_5 = x_4(D); <bb 4> : # DEBUG y => 42 # DEBUG BEGIN_STMT return 42; }
Это ещё не SSA даже
а помоему асм достаточно ясный https://godbolt.org/z/G77bd9
там не менее на этом этапе уже нет дифференциации
То есть, даже когда туда передают true?
Я не понял что ты этим хочешь сказать, но если компилятор оставляет ветвление, то он дурак
Это ещё до основных оптимизаций
Переформулируй вопрос, я тебя не понял
define dso_local i32 @_Z3foob(i1 zeroext %0) local_unnamed_addr #3 { ret i32 42 } IR, генерируемый шлангом на O3
Если ты про то, что далее мы передаем туда true, хотя сами создали контракт, что функция принимает только false, то надо понимать, что код функции генерируется независимо от вызова. Генерируя код функции компилятор ясно видит, что true передан быть не может и оптимизирует из этого знания. То что мы потом нарушаем свой же контракт - наша ошибка, которая приводит к некорректному результату
Я в слове ошибся. Даже если в функцию передают true я хотел написать.
Ниже написал - код функции не зависит от вызова
Обсуждают сегодня