相关疑难解决方法(0)

为什么在宏中使用明显无意义的do-while和if-else语句?

在许多C/C++宏中,我看到宏的代码包含在看似无意义的do while循环中.这是一些例子.

#define FOO(X) do { f(X); g(X); } while (0)
#define FOO(X) if (1) { f(X); g(X); } else
Run Code Online (Sandbox Code Playgroud)

我看不出它do while在做什么.为什么不在没有它的情况下写这个?

#define FOO(X) f(X); g(X)
Run Code Online (Sandbox Code Playgroud)

c c++ c++-faq c-preprocessor

758
推荐指数
8
解决办法
9万
查看次数

条件语句中逗号的优点是什么?

我们可以写一个if声明

if (a == 5, b == 6, ... , thisMustBeTrue)
Run Code Online (Sandbox Code Playgroud)

只有最后一个条件才能进入if身体.

为什么允许?

c++ if-statement comma

60
推荐指数
5
解决办法
4914
查看次数

如何优雅地克服无意义的C++编译器警告?

这个问题不受任何特定编译器警告的约束,以下只是一个例子.

目前我想要一个检查内部退出条件的循环:

 while( true ) {
    doSomething();
    if( condition() ) {
       break;
    }
    doSomethingElse();
}
Run Code Online (Sandbox Code Playgroud)

我不能在Visual C++中编写它 - 它会发出C4127 conditional expression is constant警告.编译器会在我脸上挥动它,虽然很明显它while(true)不能被意外地写出来.

假设我想要编译而没有警告的代码.我的服务有各种解决方法.

解决方法是使用for(;;)但感觉很愚蠢 - 为什么我想要那个奇怪的东西而不是简洁优雅的惯用语while(true)解决方法二是在行#pragma warning( suppress)之前使用,while( true )但它添加了一个巨大的横幅,它是while-statement本身的两倍.解决方法三是为整个项目禁用C4127(我已经看到它在一个真实项目中完成)但是所有可能的C4127实例也被禁用.

是否有任何优雅的方法来摆脱毫无意义的警告?

c++ compiler-construction compiler-warnings

27
推荐指数
3
解决办法
3207
查看次数

在C宏中,应该更喜欢做{...}而(0,0)而不是{...}而(0)?

一位客户最近对我雇主的C代码库进行了静态分析,并向我们提供了结果.有用的补丁包括将着名do { ... } while(0)宏更改为的请求do { ... } while(0,0).我理解他们的补丁正在做什么(使用序列运算符将evaluate 返回到第二个"0"的值,因此效果是相同的)但是不清楚他们为什么喜欢第二种形式而不是第一种形式.

有没有合理的理由为什么人们应该更喜欢第二种形式的宏观,还是我们客户的静态分析过于迂腐?

c static-analysis c-preprocessor

16
推荐指数
3
解决办法
4728
查看次数

如何禁用C4127 for do {} while(false)

可能重复:
C/C++:如何使用do-while(0); 构造没有编译器警告,如C4127?

//file error.h

        #define FAIL(message) \
        do { \
            std::ostringstream ossMsg; \
            ossMsg << message; \
            THROW_EXCEPTION(ossMsg.str());\
        } while (false)


//main.cpp

...

FAIL("invalid parameters"); // <<< warning C4127: conditional expression is constant    

...
Run Code Online (Sandbox Code Playgroud)

如您所见,警告与该警告有关do {} while(false).

我只能想出以下方法来禁用警告:

        #pragma warning( push )
        #pragma warning( disable : 4127 )
        FAIL("invalid parameters");
        #pragma warning( pop )
Run Code Online (Sandbox Code Playgroud)

但我不喜欢这个解决方案.

我也尝试将这些宏放在error.h中而没有效果.

有关如何以体面的方式抑制此警告的任何评论?

谢谢

c++ compiler-warnings visual-c++ c4127

9
推荐指数
2
解决办法
5433
查看次数

条件表达式中的常量值

关于无限循环编码风格问题中,有些人提到他们更喜欢for(;;)样式,因为while(true)样式在MSVC上给出关于条件表达式是常量的警告消息.

这让我感到非常惊讶,因为在条件表达式中使用常量值是避免#ifdef地狱的有用方法.例如,您可以在标题中:

#ifdef CONFIG_FOO
extern int foo_enabled;
#else
#define foo_enabled 0
#endif
Run Code Online (Sandbox Code Playgroud)

代码可以简单地使用条件并信任编译器在未定义CONFIG_FOO时删除死代码:

if (foo_enabled) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

每次使用foo_enabled时,不必测试CONFIG_FOO:

#ifdef CONFIG_FOO
if (foo_enabled) {
    ...
}
#endif
Run Code Online (Sandbox Code Playgroud)

这种设计模式一直在Linux内核中使用(例如,include/linux/cpumask.h在禁用SMP时将几个宏定义为1或0,在启用SMP时定义为函数调用).

MSVC警告的原因是什么?另外,有没有更好的方法来避免#ifdef hell而不必禁用该警告?或者这是一个过于广泛的警告,一般不应该启用?

c c++ warnings visual-c++

8
推荐指数
2
解决办法
4900
查看次数