在定义预处理程序语句中使用括号

时间:2014-03-03 19:34:28

标签: c c-preprocessor

所以我想知道什么时候使用

 #define xxx (yyy)

VS

 #define xxx  yyy

我的项目包含一个在AD0_ADMD_CT上有自己定义的文件,如果我想重新定义它们,我是否需要在定义中使用(AD0_ADMD_CT)或仅使用AD0_ADMD_CT?

AD0_ADMD_CT定义为

 #define    AD1_ADMD_CT     (IO_AD1.ADMD.bit.CT)

所以它会是

#define AD0_COMPARETIME     (AD0_ADMD_CT)

#define AD0_COMPARETIME     AD0_ADMD_CT

4 个答案:

答案 0 :(得分:6)

两者都没有区别。在第一种情况下,XXX替换为yyy,而(yyy)则替换为第二种情况。使用包围的惯例是避免可能发生的逻辑错误。例如,您将添加功能定义为:

#define f(N) N+N 
int a = f(5)*f(5)  

预期值为10 * 10 = 100,但输出为35,因为在编译时变为

int a = 5+5*5+5,所以使用操作员首选项规则,输出更改。

所以括号避免这些类型的错误。

答案 1 :(得分:3)

通过添加括号,您将强制括号内的参数在宏体的其余部分之前进行求值,因此如果您有

#define MULT(x, y) (x) * (y)
// now MULT(3 + 2, 4 + 2) will expand to (3 + 2) * (4 + 2)

除非您的宏有更多内容,否则它似乎不会影响您当前的情况。

答案 2 :(得分:2)

如果您的宏中有运算符,这一点非常重要。例如:

#define ADD(x,y) x + y
ADD(1,2) * 3 /* Should be 9, is 7 */

应该是:

#define ADD(x,y) (x + y)
ADD(1,2) * 3 /* 7 */

这些优先级问题也适用于@Gi Joe所说的参数,需要用parens包装以获得优先权。

然而,对于像:

这样的宏
#define MAGICNUM 3

没关系。

答案 3 :(得分:0)

要记住的一件重要事情是预处理器只是扩展宏。例如,如果您有以下行:

#define AD0_COMPARETIME_1    (AD0_ADMD_CT)
#define AD0_COMPARETIME_2    AD0_ADMD_CT

num_1 = AD0_COMPARETIME_1;
num_2 = AD0_COMPARETIME_2;

在第一次扩张之后你就拥有了这个:

num_1 = (AD0_ADMD_CT);
num_2 = AD0_ADMD_CT;

在第二次扩张后你会有这个:

num_1 = ((IO_AD1.ADMD.bit.CT));
num_2 = (IO_AD1.ADMD.bit.CT);

当表达式扩展时,可能会出现问题,如其他答案中所述。