以sum为参数的预处理器操作

时间:2018-07-24 19:07:38

标签: c c-preprocessor

对,所以我试图理解C预处理器,但是这很麻烦。

我有一个简单的

#define Square(x)(x*x) 

,我需要找出Square(5+2)在调用时返回什么。作为该领域的新手,我立即想到它将显示49,但是瞧瞧它随17一起出现了。在一段美好的时光里,我试图找出这种情况如何发生。

有人可以向我解释吗?尽可能全面,因为我有点笨。

2 个答案:

答案 0 :(得分:6)

C中的预处理器宏直接进行符号替换。所以这个:

Square(5+2)

变成这样:

(5+2*5+2)

评估为:

(5+(2*5)+2)

17岁。

您应始终在宏参数中加上括号,以防止出现此类问题:

#define Square(x) ((x)*(x)) 

然后上述调用将扩展为:

((5+2)*(5+2))

答案 1 :(得分:0)

虽然dbush已经解释了正确的parenthesising in macros,但还有一种更安全的选择:内联函数:

static inline int square(int x)
{
    return x*x;
}

不可能总是将宏转换为内联函数(例如,用于记录,如果要使用__FILE____LINE__宏),或者,但是您必须定义多个不同的版本(一个用于int,一个用于double,...),所以内联函数也不是圣杯,而是因为在之前求值,所以输入了函数,您可以避免所犯的错误类型的影响,此外,还可以避免对参数进行多次求值(有时甚至会导致不确定的行为:

int x = 7;
// inline function:
int y = square(x++); // safe
// macro:
int z = Square(x++); // expands to z = (x++)*(x++) which is undefined behaviour!

因此,如果您可以拥有内联函数而又不会增加不合理的代码开销,请选择它们...