是否存在无法通过IDENTITY可变参数宏处理的C++代码?
关于可变参数宏
IDENTITY(...) __VA_ARGS__的兼容性问题 定义如下可变参数宏:
#define IDENTITY(...) __VA_ARGS__
是否存在原本能被编译器正常接受的代码,用这个宏包裹后会被编译器拒绝?
普通的单参数宏#define IDENTITY(x) x遇到逗号就会失效(比如IDENTITY(std::pair<int, char>)会被解析为两个参数,触发宏参数不匹配的错误),但上述可变参数宏的鲁棒性要强得多——比如GCC就能正常编译以下复杂代码:
#include <stdio.h> #define IDENTITY(...) __VA_ARGS__ IDENTITY( struct does_this_work { float yes; double appears_to; }; template<class T> int what_about_this() { int x = 50, y = 0; // 这里的逗号不会触发宏错误 for(int i = 0; i < x; ++i) { printf("Hello world!"); } return 3; } )
不过确实存在部分特殊情况:
- 行为改变但不报错:如果代码依赖
__LINE__、__FILE__这类预定义宏,用IDENTITY包裹后,这些宏的取值会变成IDENTITY调用语句所在的行号/文件名,而非原代码所在的位置。比如原代码中__LINE__取的是第10行,包裹后可能变成IDENTITY起始的第8行,若代码有依赖行号的逻辑(如静态断言),可能会触发预期外的错误。 - 编译错误的极端情况:在极少数编译器特定的场景下,比如某些非标准预处理指令(如部分编译器的
#import扩展)被放在IDENTITY宏参数中时,可能会被编译器拒绝。不过这类情况非常罕见,在标准C++和主流编译器(如GCC、Clang)的支持下,绝大多数合法代码都能被该宏正确处理。
内容的提问来源于stack exchange,提问作者Joseph Garvin
相关产品推荐
相关产品推荐

