我正在阅读c ++代码,我找到了这样的定义
#define USE_VAL(X) if (&X-1) {}
有什么想法,这是什么意思?
答案 0 :(得分:7)
根据名称,它看起来像是一种摆脱“未使用的变量”警告的方法。预期用途可能是这样的:
int function(int i)
{
USE_VAL(i)
return 42;
}
如果没有这个,你可能会得到一个编译器警告:函数内部没有使用参数i
。
然而,这是一种相当危险的方法,因为它在代码中引入了未定义的行为(超出实际数组边界的指针算法是标准的Undefined)。可以将 1添加到对象的地址,但不能减去1.当然,使用+ 1
而不是- 1
,编译器可以警告“条件总是如此。“ 可能优化器将删除整个if
并且代码将保持有效,但优化器在利用“未定义的行为不可能发生”方面变得更好,这实际上可能会使代码陷入困境出乎意料。
更不用说operator&
可能因所涉及的类型而过载,这可能会导致不良副作用。
有更好的方法来实现此类功能,例如转换为void
:
#define USE_VAL(X) static_cast<void>(X)
但是,我个人的偏好是在函数定义中注释掉参数的名称,如下所示:
int function(int /*i*/)
{
return 42;
}
这样做的好处是它实际上可以防止您在将参数传递给宏后意外使用该参数。
答案 1 :(得分:1)
通常是为了避免“未使用的返回值”警告。即使通常的“cast to void”习惯用法通常适用于未使用的函数参数,gcc
-pedantic
fread
在忽略__attribute__((warn_unused_result))
等函数的返回值时也是特别严格的(一般来说,函数)标有if
),因此通常会使用“假Hash::make($data["email"]);
”来欺骗编译器,以为您正在使用返回值执行某些操作。
答案 2 :(得分:0)
宏是预处理器指令,意味着无论在何处使用,它都将被相关的代码片段替换。
并且在USE_VAL(X)之后,它解释了USE_VAL(X)将做什么。
首先取x的地址然后从中减去1。如果是0则不做任何事。
其中USE_VAL(X)将使用它将替换为if(&amp; X-1){}