Clang:表达式结果未使用三元运算符

时间:2012-02-16 18:38:24

标签: c++ clang suppress-warnings

要在我的程序中打印调试消息,我可以这样使用:

DBG(5) << "Foobar" << std::endl;

5表示消息的级别,如果调试级别小于5,则不会打印消息。目前它的实现方式如下:

#define DBG(level) !::Logger::IsToDebug((level)) ? : ::Logger::Debug

基本上IsToDebug检查是否应该打印消息,并在应该打印时返回true。 Logger::Debug是一个std :: ostream。这也适用于gcc和clang,但是clang生成表达式结果未使用的警告。根据{{​​3}},这也不想改变。

使用(void)作为前缀不起作用,它只会在?之前强制转换,导致编译错误(无法将void转换为bool)。此语法的另一个问题是它使用this email

#define DBG(x) if (::Logger::IsToDebug((x))) ::Logger::Debug这样的事情解决了这个问题,但这肯定会打破你的程序(if (foo) DBG(1) << "foo"; else ...)(我不能把整个事情都归入do { ... } while(0)宏被称为。)

我想出的唯一或多或少可行的解决方案就是这样(假设IsToDebug返回0或1):

#define DBG(level) for(int dbgtmpvar = ::Logger::IsToDebug((level)); \
                       dbgtmpvar > 0; --dbgtmpvar) ::Logger::Debug

这似乎是一种过度杀伤(不计算它的运行时开销)

1 个答案:

答案 0 :(得分:4)

我认为你应该使用三元运算符,因为它是在标准中定义的,而不是编译器扩展。要使用标准三元运算符,您还需要提供第二个表达式。为此,您可以定义一个流类,派生自std::ostream,它不会向任何地方打印任何内容。这样一个类的对象可以用作第二个表达式。

class oemptystream : std::ostream
{
     //..
};

extern oemptystream nout; //declaration here, as definition should go to .cpp

然后

#define DBG(level) ::Logger::IsToDebug((level))? nout : ::Logger::Debug

现在,如果您使用此宏,那么在运行时,表达式将减少为:

nout << "message";

或者这个,

::Logger::Debug << "message";

无论哪种方式,它都是这样的:

std::cout << "message";

所以我希望它不应该给编译器警告。