ano*_*nol 27 c++ c-preprocessor
在我的/usr/include目录中,至少有两种#define NULL 0为C++代码1量身定制的变体:
#define NULL 0 // from rpc/types.h
#define NULL (0) // from libio.h
Run Code Online (Sandbox Code Playgroud)
我觉得必须有一个反例,第一个不安全,但我无法生产它.
否则,是否有一些令人信服的论点,说明为什么在这种情况下不包括括号是安全的(例如,非正式的"正确性证明")?
1即,不包括变量#define NULL ((void*)0),它对C有用但在C++中无效.
unw*_*ind 23
我相信后者可能由于货物结果而出现,即规则/反射总是将预处理器定义放在括号中以获得良好的衡量标准.
Cad*_*hon 23
没有区别.具有较高优先级的唯一运营商::,++和--他们是不适用的0,也没有(0).
我看到的唯一有趣的区别是混淆:
#define NULL (0)
void f(int x)
{
// Do something with x
}
int main()
{
f NULL; // This code compiles
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我们谈论安全问题,可以说这#define NULL 0实际上比安全更安全#define NULL (0).
你知道,后者使你能够做到这样的事情:a = func NULL;而不是那样a = func(0);可以在生产C代码中看到它的人的大脑中产生不受控制的核反应.这是非常不安全的,你知道=)
既然没有人明确说出来......
是否有一些令人信服的论据,说明为什么在这种情况下不包括括号是安全的(例如,非正式的"正确性证明")?
括号是分组构造.他们采用表达式并将其转换为主表达式(使用标准语法中的名称).无论运算符的优先级如何,完整的主表达式都不能"进入"并由应用于它的运算符拆分.除了函数调用的注释中提到的问题之外if,这就是他们所做的一切; 它们在宏中用于确保扩展结果具有与源中看起来相同的优先级(常量看起来像原子; primary表达式的处理方式与表达式结构中的处理方式相同).
数字0是一个句法原子.它已经被定义为主表达式,因为它是一个文字常量.表达式没有内部结构供操作员拆分,优先级问题甚至不适用.由于括号没有优先级更改,因此将它包装在其中会将primary-expression转换为另一个primary-expression,即它几乎没有任何内容.
参考:C11 6.5.1"主要表达式",C++ 11 5.1.1"主要表达式".