C/C++: Как использовать - в то время как (0); создать без предупреждений компилятора как C4127?

Я часто - использование, делают - в то время как (0) конструкция в моем #defines, по причинам, описанным в этом ответе. Также я пытаюсь использовать максимально высоко предупреждение уровня из компилятора, чтобы поймать более потенциальную проблему и сделать мой код более устойчивым и межплатформенным. Таким образом, я обычно использую -Wall с gcc и /Wall с MSVC.

К сожалению, MSVC жалуется на, делают - в то время как (0) конструкция:

foo.c(36) : warning C4127: conditional expression is constant

Что я должен сделать об этом предупреждении?

Просто отключите его глобально для всех файлов? Это не делает, кажется, хорошая идея для меня.

44
задан Community 23 May 2017 в 12:25
поделиться

7 ответов

Резюме: Это предупреждение (C4127) в данном конкретном случае является тонкой ошибкой компилятора. Не стесняйтесь отключить его.

Подробно:

Это было предназначено для обнаружения ситуаций, когда логическое выражение вычисляется как константа в неочевидных ситуациях (например, if (a == a && a! = a) , и каким-то образом он превратил while (true) и другие полезные конструкции в недопустимые.

Microsoft рекомендует использовать for (;;) для бесконечного цикла, если вы хотите, чтобы это предупреждение было включено, и в вашем случае нет решения. Это одно из очень немногих предупреждений уровня 4, которые моя компания разрешает отключить.

45
ответ дан 26 November 2019 в 21:46
поделиться

#define STUFF для (bool b = true; b;) do {f (); г(); b = false;} while (b) ?

#define STUFF для (;;) {f (); г(); перерыв;} ?

1
ответ дан 26 November 2019 в 21:46
поделиться

Вы можете использовать #pragma warning, чтобы:

  1. сохранить состояние
  2. отключить предупреждение
  3. записать неправильный код
  4. вернуть предупреждение в предыдущее состояние

(вам нужен символ # перед прагмами, но SO трудно справиться с ними и одновременно форматировать)

#pragma warning( push )
#pragma warning( disable: 4127 )
// Your code
#pragma warning( pop ) 

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

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

0
ответ дан 26 November 2019 в 21:46
поделиться

Должен сказать, я никогда не беспокоился о конструкции do.. while в макросах. Весь код в моих макросах заключен в фигурные скобки, но без do - .. while. Например:

#define F(x) \
    {           \
        x++;    \
    }           \

int main() {
    int a = 1;
    F(a);
    printf( "%d\n", a );
}

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

0
ответ дан 26 November 2019 в 21:46
поделиться

Эта штука «while (0)» является хакерской и только что развернулась, чтобы вас укусить.

Предлагает ли ваш компилятор #pragma для выборочно и локально отключение конкретных сообщений об ошибках? Если так, это может быть разумной альтернативой.

1
ответ дан 26 November 2019 в 21:46
поделиться

Есть решение, но оно добавит больше циклов в ваш код. Не используйте явное значение в условии while.

Можно сделать так:

file1.h

extern const int I_am_a_zero;
#define MY_MACRO(foo,bar) \
do \
{ \
} \
while(I_am_a_zero);

переменная I_am_a_zero должна быть определена в каком-то .c файле.

В любом случае это предупреждение не появляется в GCC :)

См. этот родственный вопрос.

.
0
ответ дан 26 November 2019 в 21:46
поделиться

Возможно, вашему коду нужно больше сов:

do { stuff(); } while (0,0)

или меньше фотогеничности, но и меньше предупреждений:

do { stuff(); } while ((void)0,0)
28
ответ дан 26 November 2019 в 21:46
поделиться