Peter пишет:И вы же сами расхваливали способность компилятора оптимизировать код,
почему же вам не нравится -O3?
я не восхвалял. Я вам доказал, что оптимизированный код изменён до полной неузнаваемости. Если ваш код на 146% соответствует стандарту, то он будет работать точно также по результату, иначе — как карта ляжет. Причём ошибка может таится в самом неожиданном месте.
ну вот вам пример: http://blog.llvm.org/2011/05/what-every … ow_14.html
void contains_null_check(int *P) {
int dead = *P;
if (P == 0)
return;
*P = 4;
}
компилятор _может_ превратить в
void contains_null_check_after_RNCE_and_DCE(int *P) {
*P = 4;
}
А может и не превратить. Зависит от фазы луны.
А всего-то была проблема в том, что в данном коде разименовывается указатель P. Причём результат ни на что не влияет, т.к. переменная dead НЕ используется. На первый взгляд: ну и что? На второй: а действительно, что?
Фишка в том, что разименованный NULL, это UB. А UB это вовсе не "непонятный результат", всё намного хуже, это неопределённое ДЕЙСТВИЕ. Т.е. компилятор в данном случае, по стандарту(sic!) может рожать любой код. Ну при -O3 он естественно ничего не рожает, ибо "ничего" самое быстрое. Проблема в том, что это "ничего" намного сильнее, чем вы думаете, ВНЕЗАПНО, компилятор не только ничего не делает для разименования, но и считает, что само разименование невозможно! (имеет право, да). А значит, P ВСЕГДА НЕ NULL! А раз так, то и проверка не нужна.
Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)