5

考虑以下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 手册说:

只有当它的名称后面带有一对括号时,才会展开类似函数的宏。如果你只写名字,它就会被单独留下

这是标准化的还是只是按惯例完成的?

4

1 回答 1

5

是的,这里的行为是明确定义的。

您的宏max是一个类似函数的宏(即,当您定义它时,它的名称后面紧跟一个左括号并接受参数)。

如果使用后跟左括号,则代码中max稍后的使用只是对该宏的调用。max因此,这些不会调用max宏:

int max;
max = 42;

但是这些都会调用 max 宏:

max(1, 2)
max (1, 2)
max
(
    1, 2
)
max()

(请注意,最后一行格式错误,因为参数的数量与参数的数量不匹配。不过,这仍然是宏调用,会导致编译错误。)

这种行为是由 C 语言标准规定的。C99 §6.10.3/10 指出,在定义了类似函数的宏之后,

类似函数的宏名称的每个后续实例后跟(作为下一个预处理标记的 a 引入了预处理标记的序列,该序列被定义中的替换列表替换(宏的调用)。

于 2012-06-11T16:48:10.847 回答