Я часто - использование, делают - в то время как (0) конструкция в моем #defines, по причинам, описанным в этом ответе. Также я пытаюсь использовать максимально высоко предупреждение уровня из компилятора, чтобы поймать более потенциальную проблему и сделать мой код более устойчивым и межплатформенным. Таким образом, я обычно использую -Wall
с gcc и /Wall
с MSVC.
К сожалению, MSVC жалуется на, делают - в то время как (0) конструкция:
foo.c(36) : warning C4127: conditional expression is constant
Что я должен сделать об этом предупреждении?
Просто отключите его глобально для всех файлов? Это не делает, кажется, хорошая идея для меня.
Резюме: Это предупреждение (C4127) в данном конкретном случае является тонкой ошибкой компилятора. Не стесняйтесь отключить его.
Подробно:
Это было предназначено для обнаружения ситуаций, когда логическое выражение вычисляется как константа в неочевидных ситуациях (например, if (a == a && a! = a)
, и каким-то образом он превратил while (true)
и другие полезные конструкции в недопустимые.
Microsoft рекомендует использовать for (;;)
для бесконечного цикла, если вы хотите, чтобы это предупреждение было включено, и в вашем случае нет решения. Это одно из очень немногих предупреждений уровня 4, которые моя компания разрешает отключить.
#define STUFF для (bool b = true; b;) do {f (); г(); b = false;} while (b)
?
#define STUFF для (;;) {f (); г(); перерыв;}
?
Вы можете использовать #pragma warning, чтобы:
(вам нужен символ # перед прагмами, но SO трудно справиться с ними и одновременно форматировать)
#pragma warning( push )
#pragma warning( disable: 4127 )
// Your code
#pragma warning( pop )
Вы хотите, чтобы предупреждения выдвигались / выдавались, а не отключать / включать, потому что вы не хотите мешать аргументы командной строки, которые могут быть выбраны для включения / выключения предупреждений (кто-то может использовать командную строку, чтобы отключить предупреждение, вы не хотите, чтобы оно снова включалось принудительно ... приведенный выше код имеет дело с этим).
Это лучше, чем глобальное отключение предупреждения, поскольку вы можете управлять им только для той части, которая вам нужна. Также вы можете сделать его частью макроса.
Должен сказать, я никогда не беспокоился о конструкции do.. while в макросах. Весь код в моих макросах заключен в фигурные скобки, но без do - .. while. Например:
#define F(x) \
{ \
x++; \
} \
int main() {
int a = 1;
F(a);
printf( "%d\n", a );
}
Кроме того, мой собственный стандарт кодирования (и неформальная практика в течение многих лет) заключался в том, чтобы все блоки, где бы они ни происходили, были заключены в фигурные скобки, что также более или менее устраняет проблему.
Эта штука «while (0)» является хакерской и только что развернулась, чтобы вас укусить.
Предлагает ли ваш компилятор #pragma
для выборочно и локально отключение конкретных сообщений об ошибках? Если так, это может быть разумной альтернативой.
Есть решение, но оно добавит больше циклов в ваш код. Не используйте явное значение в условии 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 :)
См. этот родственный вопрос.
.Возможно, вашему коду нужно больше сов:
do { stuff(); } while (0,0)
или меньше фотогеничности, но и меньше предупреждений:
do { stuff(); } while ((void)0,0)