【问题标题】:C++, GCC: avoid evaluation of useless expressionsC++、GCC:避免评估无用的表达式
【发布时间】:2012-02-12 00:13:08
【问题描述】:

我用operator<< 定义了一个Debug 类(类似于Qt 中的qDebug)以将数据流式传输到stdout。

根据其模板参数(这又依赖于宏DEBUG),Debug 将被特化:一个特化的operator<< 将打印数据,而另一个特化将是安静的.

以下为静音版:

template< bool quiet = true >
class _Debug
{
public:
    template< typename T >
    _Debug& operator<<( const T & )
    {
        return *this;
    }
};

然而,我注意到,即使是安静版本,operator&lt;&lt; 的参数也会被评估:

Debug<1>() << "Var " << var.name();

我可以通过分析器看到,在运行上述代码时,即使 Debug&lt;1&gt; 是 _Debug 的安静特化,也会评估表达式 "Var" 和 var.name()。

有什么办法可以避免这种情况吗?也许我应该将一些选项传递给 GCC?

我认为使用模板的类似解决方案会比使用宏的解决方案更简洁,性能更好,但可能是错误的......

【问题讨论】:

  • 不要将你的东西命名为_This,它是为实现保留的。
  • 编译器如何知道 var.name() 正在做一些有效的事情或者是不需要编译的事情?
  • C++11?传递一个仅在调试模式下执行的 lambda 函数?虽然,我一直只是使用DEBUG &amp;&amp; cout &lt;&lt; "Var"; 或类似的东西。
  • 表达式是否被评估是否重要?如果最终的函数调用什么都不做,优化器应该注意这一点。然后只需申请专业化。
  • @Kerrek:如果表达式调用库或外部模块中的函数,编译器可能没有足够的信息来优化它。

标签: c++ templates gcc macros evaluation


【解决方案1】:

我不确定如何在没有宏的情况下实现这一点。所以作为参考,这里有一个类似于 google-glog 中使用的宏:

#define LOG (quiet) ? (void)0 : your_logging_object

quiet 是一个布尔值。然后在您的代码中的其他地方:

LOG << some_var;

【讨论】:

  • 跳过条件编译,使用变量作为三元运算符控制表达式。
  • @thesamet:在我的代码中我有类似的东西:auto dbg = Debug&lt;5&gt;(); while( ... ) dbg &lt;&lt; something;。有没有办法调整您的解决方案以处理这种情况?
  • #define dbg (quiet) ? (void)0 : your_real_dbg 会做吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多