Какой смысл выдавать предупреждение компилятора для "while (true)", а не для "for (;;)"? - PullRequest
10 голосов
/ 10 марта 2011

Когда я компилирую код C ++ с Visual C ++ 9 с «уровнем предупреждения 4» следующее:

while( true ) {
   //loop body with break on certain condition
}

и следующее:

for( ; true; ) {
   //same loop body
}

оба вызывают C4127: conditional expression is constant предупреждение, но следующее:

for( ; ; ) {
   //same loop body
}

компилируется без предупреждения.

Почему такая разница, особенно между вторым и третьим вариантом?

Ответы [ 5 ]

10 голосов
/ 10 марта 2011

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

7 голосов
/ 10 марта 2011

Причина проста, хотя и глупа.

Важно диагностировать бесконечный цикл, но такое может быть неочевидно:

while(i >= 0) { --i; } // infinite if i unsigned

while(SOME_MACRO(i)) // err, depends on the expansion of macros

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

Просто кажется, что VC ++ слишком далеко продвинулся здесь, и вместо рассмотрения тавтологических условий предупреждает для всех true или false условий, которые он может найти, даже если они уже четко указаны в коде.

4 голосов
/ 10 марта 2011

Нет смысла.В конце концов, спецификация языка говорит ($ 6.5.3 / 2),

Любое или оба условия и выражения могут быть опущены. Отсутствующее условие делает подразумеваемое условие while эквивалентным while (true).

Таким образом, for ( ; ; ) эквивалентно while(true) даже в соответствии со Стандартом.Поэтому я не вижу причин, по которым компилятор должен выдавать предупреждение в одном случае, а не в другом!

-

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

Я имею в виду, for ( ;; ) является более вероятным опечаткой , чем явное упоминание о состоянии в for ( ;true; ).Последнее говорит программисту о четких и явных намерениях.Как говорит Стив в комментарии:

Для значения int у char x = y эквивалентно char x = (char) y, но вы можете получить предупреждение длянеявное сужающее преобразование для первого, но не второго.

Таким образом, явное намерение не должно получать предупреждение, в то время как неявное намерение должно получать!

4 голосов
/ 10 марта 2011

Конструкция for ( ;; ) является каноническим способом преднамеренного кодирования "бесконечного" цикла.Я мог представить, что разработчики компилятора не захотели выдавать предупреждение за это.

1 голос
/ 10 марта 2011

Предупреждение компилятора здесь, чтобы помочь обнаружить потенциальные ошибки. Использование условия true в цикле while, вероятно, является ошибкой. Например, в следующем коде это, вероятно, ошибка, и я хотел бы, чтобы компилятор предупредил меня об этом:

unsigned int x;
// ...
while (x >= 0) {
    // ...
}

В такой ситуации в оптимизированной сборке компилятор, вероятно, определит, что условие всегда истинно (поскольку целое число без знака не может быть меньше 0). Таким образом, существует необходимость обнаружения условия true в цикле while. Я думаю, что тот, кто писал об обнаружении такой ошибки, не имел особого случая while (true), так как существует простой способ сделать бесконечный цикл с for (;;).

Вы можете прочитать здесь , как принимается решение добавить предупреждение или нет в Visual Studio (пример около C#, но я полагаю, что у команды такое же правило для предупреждение в C++).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...