【问题标题】:Why and when to use __noop?为什么以及何时使用 __noop?
【发布时间】:2013-01-05 17:10:28
【问题描述】:

我正在阅读有关 __noop 的信息,而 MSDN 示例是

#if DEBUG
   #define PRINT   printf_s
#else
   #define PRINT   __noop
#endif

int main() {
   PRINT("\nhello\n");
}

而且我没有看到仅仅拥有一个空宏的好处:

#define PRINT

生成的代码是一样的。使用__noop 的有效示例是什么?

【问题讨论】:

  • 我猜在某些情况下“没有声明”会改变事情的运作方式。不完全确定我现在能想到一个。
  • 顺便说一句,他们的示例有点狡猾,因为它会导致在调试和发布模式下具有不同类型的表达式。但它不像调试模式中的类型那样狡猾,无论PRINT 的“参数”是什么!可变参数宏允许更好地定义#define PRINT(...) ((void)printf_s(__VA_ARGS__))#define PRINT(...) ((void)0),这也阻止了您尝试使用&PRINT 获取函数指针。

标签: c++ visual-c++ intrinsics


【解决方案1】:

__noop 内在函数指定应忽略函数并解析参数列表但不会为参数生成代码。它旨在用于接受变量的全局调试函数参数数量。

在您的情况下,参数显然是一个无副作用的表达式,可以轻松优化,所以没关系。

但如果参数表达式有副作用或太复杂以至于编译器无法证明它正常终止并且没有副作用,那么使用 __noop 可以防止对该表达式进行潜在的昂贵评估。

第二个好处是它在语法上表现得像一个带有可变数量参数的函数调用。所以用它代替函数调用不会影响程序的解析。使用其他一些替换(如空字符串),在某些情况下可能会出现问题。

【讨论】:

  • 是的,我想就是这样。 :)
【解决方案2】:
#define PRINT
extern int some_complicated_calculation();
PRINT("%d\n", some_complicated_calculation());

即使您不想要结果也会调用该函数。

使用__noop,该函数不会被调用。

您可以(假设编译器支持可变参数宏)定义 PRINT 以忽略参数;但是它们根本不会被解析,并且如果您更改它们周围的代码而不编译定义PRINT 的变体来做某事,它们可能会变得无效。使用__noop,参数仍然被解析,因此更有可能保持有效。

【讨论】:

    【解决方案3】:

    怎么样:

    if (condition)
      PRINT("hello\n");
    next_statetment;
    

    我认为,如果没有 __noop,在 Release 模式下,'next_statetment' 只会在 'condition' 为真时执行,这是一个很难找到的 bug。

    【讨论】:

      猜你喜欢
      • 2013-06-13
      • 2021-01-24
      • 2017-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-12
      • 1970-01-01
      • 2023-03-03
      相关资源
      最近更新 更多