#if sizeof(int) != 4
/* do something */
Run Code Online (Sandbox Code Playgroud)
在内部使用sizeof #if不起作用#define,为什么?
#define size(x) sizeof(x)/sizeof(x[0]) /*works*/
Run Code Online (Sandbox Code Playgroud)
小智 27
没有什么是邪恶的 - 一切都可能被误用,或者在你的情况下被误解.该sizeof运营商是一个编译器的功能,但是编译器的功能是不提供给预处理器(编译器介入之前运行),因此不能使用#if预处理指令.
但是,当你说:
#define size(x) sizeof(x)/sizeof(x[0])
Run Code Online (Sandbox Code Playgroud)
并使用它:
size(a)
Run Code Online (Sandbox Code Playgroud)
预处理器执行一个文本替换,交给编译器:
sizeof(a)/sizeof(a[0])
Run Code Online (Sandbox Code Playgroud)
简短的回答是预处理器表达式仅提供对由其他预处理器宏和常量组成的表达式的有意义的评估.
试试这个,你不会得到一个错误:
#if sizeof < 2
int f(int x) { return x; }
#endif
Run Code Online (Sandbox Code Playgroud)
如果生成程序集,您会发现sizeof < 2编译该函数而sizeof >= 2不是.都不会返回错误.
这是怎么回事?事实证明,除了预处理器宏本身之外,预处理器("宏")表达式中的所有标识符都替换为0.所以上面#if的内容与说:
#if Easter_Bunny < 2
Run Code Online (Sandbox Code Playgroud)
要么
#if 0 < 2
Run Code Online (Sandbox Code Playgroud)
这就是为什么sizeof在预处理器表达式中错误地使用运算符时实际上不会出现任何类型的错误.
实际上,它sizeof是一个运算符,但它也是一个标识符,并且本身不是宏的标识符都会0在预处理程序表达式中变成.预处理器至少在概念上运行在编译器之前.它可以将非C语法转换为C,所以在它运行的时候,C程序还没有被解析过.现在还无法引用实际的C对象:它们不存在.
当然,sizeof定义的替换文本中的a只是简单地传递给编译器,因为它是使用宏的替换文本.