Почему gcc не выдает предупреждение при неопределенном поведении в коде внутри?

Я только что прочитал этот FAQ по C++ о неопределенном поведении и точках последовательности и немного поэкспериментировал. В следующем коде gcc-4.5.2 выдает предупреждение только в строке, упомянутой в комментарии к коду, хотя предыдущая строка тоже показывает неопределенное поведение, не так ли? Вы не можете сказать, какой операнд сложения выполняется первым (как + не точка последовательности). Почему gcc тоже не выдает предупреждение в этой строке?

int i=0;
int j=0;

int foo(void) {
    i=1;
    return i;
}

int main(void) {
    i = i + foo(); 
    j = j + (j=1); //Here is a rightly warning
    return 0;
}

Спасибо за помощь.

3 ответа

Решение

Поведение i = i + foo(); не указано, но не определено Undefined означает, что разрешено любое возможное поведение, даже прерывание программы. Unspecified означает, что либо i вычисляется первым, либо foo(). Да, foo пишет в тот же i, но, поскольку это происходит в отдельном операторе, существует точка последовательности до и после этого хранилища.

Линия i = i + foo(); в вашей программе не указано, но не определено.

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

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

Людям видно, что вызов foo() изменит i, но для компьютерной программы это трудно увидеть. Это просто не предназначено, чтобы увидеть это.

Другие вопросы по тегам