Постоянное значение в условном выражении
В вопросе стиля кодирования о бесконечных циклах некоторые люди упомянули, что предпочитают стиль for (;;), потому что стиль while (true) дает предупреждающие сообщения на MSVC о постоянном условном выражении.
Это очень меня удивило, так как использование постоянных значений в условных выражениях - полезный способ избежать #ifdef hell. Например, вы можете иметь в своем заголовке:
#ifdef CONFIG_FOO
extern int foo_enabled;
#else
#define foo_enabled 0
#endif
И код может просто использовать условное выражение и доверять компилятору, чтобы он удалил мертвый код, когда CONFIG_FOO не определен:
if (foo_enabled) {
...
}
Вместо того, чтобы тестировать CONFIG_FOO каждый раз, когда используется foo_enabled:
#ifdef CONFIG_FOO
if (foo_enabled) {
...
}
#endif
Этот шаблон проектирования используется все время в ядре Linux (например, include/linux/cpumask.h определяет несколько макросов в 1 или 0, когда SMP отключен и вызов функции, когда SMP включен).
В чем причина этого предупреждения MSVC? Кроме того, есть ли лучший способ избежать #ifdef hell без необходимости отключать это предупреждение? Или это слишком широкое предупреждение, которое не должно быть включено вообще?
Ответы
Ответ 1
Предупреждение автоматически не означает, что код плохой, просто подозрительный.
Лично я начинаю с позиции включения всех предупреждений, которые я могу, а затем отключить все, что окажется более раздражающим, чем полезным. Первый, который срабатывает в любое время, когда вы делаете что-либо в bool, обычно является первым.
Ответ 2
Я думаю, что причина предупреждения заключается в том, что вы можете непреднамеренно иметь более сложное выражение, которое оценивает константу, не осознавая ее. Предположим, что в заголовке есть такое объявление:
const int x = 0;
а затем, вдалеке от объявления x, у вас есть условие вроде:
if (x != 0) ...
Вы можете не заметить, что это постоянное выражение.
Ответ 3
Я считаю, что это поймать такие вещи, как
if( x=0 )
когда вы имели в виду
if( x==0 )
Ответ 4
Простым способом избежать предупреждения будет:
#ifdef CONFIG_FOO
extern int foo_enabled;
#else
extern int foo_enabled = 0;
#endif