示例代码:
#define FOO(...) You passed: #__VA_ARGS__
FOO(1,2,3)
FOO()
使用 Visual C++(版本 14 CTP)进行预处理,得到:
You passed: "1,2,3"
You passed:
在最后一行,#__VA_ARGS__
变成了虚无。我宁愿把它变成“”。
对于应该发生的事情是否有明确的参考?我用谷歌搜索了很多,但找不到。
任何建议的解决方法也将很有用。
示例代码:
#define FOO(...) You passed: #__VA_ARGS__
FOO(1,2,3)
FOO()
使用 Visual C++(版本 14 CTP)进行预处理,得到:
You passed: "1,2,3"
You passed:
在最后一行,#__VA_ARGS__
变成了虚无。我宁愿把它变成“”。
对于应该发生的事情是否有明确的参考?我用谷歌搜索了很多,但找不到。
任何建议的解决方法也将很有用。
根据6.10.3.2 # 运算符(C11):
语义
2 - [...] 对应于空参数的字符串文字是
""
. [...]
所以我认为 MSVC 在这里是不正确的。
我会使用字符串文字连接来解决这个问题:
#define FOO(...) You passed: "" #__VA_ARGS__
标准 (ISO14882:2011(e)) 中的段落有点长,但很清楚:
2字符串文字是字符串文字没有前缀。如果在替换列表中,参数前面紧跟 # 预处理标记,则两者都被单个字符串文字预处理标记替换,该预处理标记包含对应参数的预处理标记序列的拼写。参数的预处理标记之间每次出现的空白都会成为字符串文字中的单个空格字符。删除第一个预处理标记之前和包含参数的最后一个预处理标记之后的空白。否则,参数中每个预处理标记的原始拼写将保留在字符串文字中,但产生字符串文字和字符文字的拼写的特殊处理除外:在每个 " 之前插入一个 \ 字符与空参数对应的字符串文字是“”。# 和 ## 运算符的求值顺序未指定。
而且因为
2替换列表中出现的标识符
__VA_ARGS__
应被视为参数,可变参数应形成用于替换它的预处理标记。
这对于 varags 和普通参数是一样的。