C ++ 11:逗号运算符的左操作数无效

时间:2015-03-27 14:25:03

标签: c++11 null

在我的项目中开始使用C ++ 11之后,我收到了这个警告

这是提供警告的代码段:

    std::string errortext = "cannot find suitable conversion for %d", index;
    LogToFile(NULL, errortext);
    Assert(false && "cannot find suitable conversion");
    return NULL;

如果我删除了NULL,那段代码仍然会做同样的事情吗? 或者有什么方法可以解决它吗?

#ifndef Assert
    #include <assert.h>
    #define Assert assert
    #define LogToFile (void)(0);
#endif

2 个答案:

答案 0 :(得分:1)

看起来有些时候,LogToFile被定义为带参数的宏,有时则没有:

#if 0
#define LogToFile(x, y) some_log_function(x, y, __FILE__, __LINE__, __FUNCTION__)
#else
#define LogToFile (void)(0);
#endif

这导致扩展如下:

(void)(0);(NULL, errortext);

和你看到的警告。

很多更好的选择是在两种情况下都使用相同数量的参数:

#if 0
#define LogToFile(x,y) some_log_function(x, y, __FILE__, __LINE__, __FUNCTION__)
#else
#define LogToFile(x,y) (void)(y)
#endif

事实上,原始版本被严重破坏,因为它从一个语句变为两个语句,如果它是条件或循环的受控语句,它将不会按预期运行。

答案 1 :(得分:1)

LogToFile被定义为“类似对象”的宏(不带参数的宏),而不是像函数一样的宏。

鉴于定义:

#define LogToFile (void)(0);

这一行:

LogToFile(NULL, errortext);

扩展到:

(void)(0); (NULL, errortext);

这是两个单独的陈述。第二个是表达式语句,其中表达式是带括号的逗号表达式(逗号是逗号运算符,而不是参数分隔符)。逗号运算符的左操作数为NULL

假设它总是需要两个参数,您可以将定义更改为:

#define LogToFile(arg1, arg2) ((void)(0))

如果它需要可变数量的参数,您可以将其定义为可变参数宏:

#define LogToFile(...) ((void)(0))

(注意:我在定义中添加了额外的括号。)