ANSI C99标准中预定议了两个宏,__FILE__和__LINE__。这两个宏在断言中很有
用处。但是,这两个宏的类型却不相同:__FILE__展开为一个字符串,__LINE__
展开为一个整数。
这也就意味着,你可以写出如下代码:
printf("Error at file " __FILE__); //注意中间没有逗号
而以下代码却是非法的:
printf("Error at line" __LINE__);
解决这个问题的第一个想法可能是使用“#”宏操作符:
#define stringify(x) #x
printf("Error at line " stringify(__LINE__) );
但是这只能产生如下输出
Error at line __LINE__
ISO/IEC 9899:1999 中有这样一段话
After all parameters in the replacement list have been substituted and
# and ## processing has taken place, all placemarker preprocessing
tokens are removed. Then, the resulting preprocessing token sequence is
rescanned, along with all subsequent preprocessing tokens of the source
file, for more macro names to replace.在所有替换列表中的参数和 #及##预处理操作符的置换工作都已经完成,所有占位符都已经被移除之后,其预处理结果将被重新扫描并进行尽可能多的宏替换。
所以,针对上述问题,我们可以利用宏替换重复执行的特性来间接解决,方案如
下:
#define stringify1(x) #x
#define stringify(x) stringify1(x)
printf("Error at line " stringify(__LINE__) );
其宏替换步骤如下:
0 printf("Error at line " stringify(__LINE__) );
1 printf("Error at line " stringify1(3) );
2 printf("Error at line " "3" );
其结果与以下调用等价:
printf("Error at line 3" );