算术表达式作为c中宏的参数

使用宏与预处理器指令#define我写了以下两个代码。

  • 第一个代码传递表达式,例如a + b

_valid_pagesize(A + B)

  • 在第二个代码中

C = A + B

然后将此c作为参数传递给宏。

_valid_pagesize(c)中

第二个代码运行完美,而第一个代码没有。 我们不能像在函数的情况下那样将表达式作为参数传递给宏吗? 为什么不..?

将表达式作为参数传递的代码:

#include #include #define _valid_pagesize(_newsize) (!(_newsize % 0x80000000)?1: \ (!(_newsize % 0x40000000)?1: \ (!(_newsize % 0x10000000)?1: \ (!(_newsize % 0x4000000) ?1:0)))) int main(int argc, char* argv[]){ uint64_t size[2]; size[0]=atoi(argv[1]); size[1]=atoi(argv[2]); if(_valid_pagesize(size[0]+size[1])){ printf("success\n"); } return 0; } 

带有宏的规则#1是将所有参数括在括号中,以避免您遇到的问题。

 #define _valid_pagesize(_newsize) (!((_newsize) % 0x80000000)?1: \ (!((_newsize) % 0x40000000)?1: \ (!((_newsize) % 0x10000000)?1: \ (!((_newsize) % 0x4000000) ?1:0)))) 

a+b传递给宏时,它会扩展为

 a + b % 0x40000000 

由于%优先级高于+ ,因此无法获得预期的结果。 通过将参数括在括号中,宏扩展为

 (a + b) % 0x40000000 

它按预期工作。

宏参数在传递给宏之前不会被评估,因为宏扩展在编译之前发生。 相反,实际表达式将不变地传递到宏中,并替换为参数名称的所有匹配项。 因此, _valid_pagesize(a+b)扩展为:

 (!(a+b % 0x80000000)?1: \ (!(a+b % 0x40000000)?1: \ (!(a+b % 0x10000000)?1: \ (!(a+b % 0x4000000) ?1:0)))) 

现在,它产生错误答案的原因显然是显而易见的。 请关注user3386109关于将参数括在括号中的建议。

将_newsize放在宏扩展中的大括号内