【问题标题】:Void cast macro explaination虚空施法宏说明
【发布时间】:2016-09-22 01:18:28
【问题描述】:

希望对以下代码得到一些澄清/解释

#define NOOP(x) ((void)(x))

void my_function(int x)
{
     NOOP(x);
}

此宏可防止未使用的参数警告。

我有两个问题-

  1. 所以我们通过使用这个宏来转换任何 x 是无效的。什么是 当我们 void cast 某些东西时真的会发生吗?
  2. 为什么(void)(x) 周围多了一组括号

谢谢

【问题讨论】:

  • 1.施放无效什么都不做。 2. NOOP(1+2)怎么样?

标签: c++


【解决方案1】:

至于发生的事情,绝对没有什么,这就是重点。只是对变量的引用,但绝对不做任何事情。编译器尽职尽责地处理它,注意到参数已被使用,然后丢弃所有内容并且不生成任何实际代码。

就括号而言:

对可能在表达式中使用的宏使用括号是一种很好的做法,即使在不需要时也是如此。

例如,假设代码中有一个简单的宏,它在屏幕上绘制一个窗口。执行它的库会在窗口周围添加一个边框,例如 6 像素长。这个宏计算窗口的总宽度。这个宏的简单实现会这样写:

#define ACTUAL_WIDTH(w)  w+6

现在,假设您的代码要计算两个窗口的实际宽度。两个窗口都是 100 像素宽:

int total_width=ACTUAL_WIDTH(100)*2;

你认为会发生什么?回想一下,宏替换基本上只是一个简单的文本替换,所以这就是实际编译的内容:

int total_width=100+6*2;

这是完全错误的。您想在宏中添加一组额外的括号,以便编译正确的代码:

int total_width=(100+6)*2;

这就是为什么您经常会在宏中看到一组额外的括号,这些括号可以在表达式中使用。不仅如此,像这样的宏也会在其参数周围加上括号,所以它可能是:

#define ACTUAL_WIDTH(w)  ((w)+6)

这就是为什么您会在宏中看到一组额外的括号。养成将它们始终粘贴到您编写的每个宏中并且安全的习惯会更容易;而不是每次都浪费时间弄清楚是否真的需要它们。

使用良好的编程习惯将避免许多常见的错误。

【讨论】:

    【解决方案2】:

    来自C++14 standard working draft from November 2014 的第 5.2.9 节第 6 段:

    任何表达式都可以显式转换为 cv void 类型,在这种情况下,它变成了废弃值表达式。

    正如其他人所说,额外的括号通过有效地将表达式与可能在它周围的代码隔离开来防止任何不良影响。尽管在这种情况下,我相信通过不包括外括号在实际应用中不太可能感受到任何不良影响,特别是如果您只是使用它来避免函数中未使用的变量警告。将它们排除在外是不值得冒险的。

    为了证明这一点,我提出了一个非常人为的示例,该示例会导致代码无意执行,因为存在比 C 风格转换具有更高优先级的运算符。

    #include <iostream>
    
    #define NOOP(x) ((void)(x))
    #define MYNOOP(x) (void) (x)
    
    struct A
    {
      bool operator()(void) {
        std::cout << "Called function unintentionally" << std::endl;
        return true;
      }
    };
    
    int main() {
      A i;
      MYNOOP(i)();
      //NOOP(i)(); // error: called object type 'void' is not a function or function pointer
      return 0;
    }
    

    【讨论】:

      【解决方案3】:

      正如你所说,你的代码不会显示未使用的变量警告,因为你正在使用你的变量 'x' ,但你只是什么都不做,你将它传递给一个不做任何重要的函数(NOOP(x ) -- 什么都不做,但是编译器看到你正在尝试使用 x 变量) 所以它不会告诉你你没有使用你的变量

      【讨论】:

        猜你喜欢
        • 2019-08-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多