考虑以下 C 计划(忽略双重副作用问题):
#define max(a, b) (a>b?a:b)
int main(void){
int max = max(5,6);
return max;
}
GCC预处理器将其转换为:
int main(void){
int max = (5>6?5:6);
return max;
}
这非常好,因为您不必担心max
和max()
之间的无意碰撞。 GCC manual说:
类似函数的宏只有在其名称后面带有一对括号后才会展开。如果你只写下这个名字,那就不用了
这是标准化的还是按惯例完成的事情?
答案 0 :(得分:5)
是的,这里的行为定义明确。
您的宏max
是一个类似于函数的宏(即,当您定义它时,其名称后面紧跟左括号并且它接受参数)。
如果使用max
后跟左括号,则稍后在代码中使用max
只是对该宏的调用。因此,这些不会调用max
宏:
int max;
max = 42;
但是这些都会调用max macro:
max(1, 2)
max (1, 2)
max
(
1, 2
)
max()
(注意,最后一行是格式错误的,因为参数的数量与参数的数量不匹配。但这仍然是一个宏调用,并且会导致编译错误。)
此行为是由C语言标准强制执行的。 C99§6.10.3/ 10指出在定义了类似函数的宏之后,
类函数宏名称后跟
(
作为下一个预处理标记的每个后续实例引入了预处理标记序列,该标记由定义中的替换列表(宏的调用)替换。