简体   繁体   English

什么是#__VA_ARGS__应该在没有传递参数时生成?

[英]What is #__VA_ARGS__ supposed to generate when there are no arguments passed?

Example code: 示例代码:

#define FOO(...) You passed: #__VA_ARGS__
FOO(1,2,3)
FOO()

Preprocess with Visual C++ (version 14 CTP), get: 使用Visual C ++(版本14 CTP)进行预处理,得到:

You passed: "1,2,3"
You passed:

In the last line, #__VA_ARGS__ is turned into nothingness. 在最后一行, #__VA_ARGS__变成了虚无。 I would prefer it turned into "". 我希望它变成“”。

Is there a definitive reference for what is supposed to happen? 对于应该发生的事情,是否有明确的参考? I Googled a lot but couldn't find it. 我用Google搜索了很多但却找不到它。

Any suggested work-around would also be useful. 任何建议的解决方案也很有用。

Per 6.10.3.2 The # operator (C11): 6.10.3.2#运算符 (C11):

Semantics 语义

2 - [...] The character string literal corresponding to an empty argument is "" . 2 - [...]对应于空参数的字符串文字是"" [...] [...]

So I think MSVC is incorrect here. 所以我认为MSVC在这里是不正确的。

I would workaround this using string literal concatenation: 我会使用字符串文字串联来解决这个问题:

#define FOO(...) You passed: "" #__VA_ARGS__

The paragraph in the standard (ISO14882:2011(e)) is a little bit lengthy, but its quite clear: 标准中的段落(ISO14882:2011(e))有点冗长,但很明显:

16.3.2 The # operator 16.3.2#运算符

2 A character string literal is a string-literal with no prefix. 2 字符串文字是一个没有前缀的字符串文字 If, in the replacement list, a parameter is immediately preceded by a # preprocessing token, both are replaced by a single character string literal preprocessing token that contains the spelling of the preprocessing token sequence for the corresponding argument. 如果在替换列表中,参数前面紧跟#预处理标记,则它们都被单个字符串文字预处理标记替换,该标记包含相应参数的预处理标记序列的拼写。 Each occurrence of white space between the argument's preprocessing tokens becomes a single space character in the character string literal. 参数的预处理标记之间每次出现的空格都会成为字符串文字中的单个空格字符。 White space before the first preprocessing token and after the last preprocessing token comprising the argument is deleted. 在第一个预处理标记之前和包含该参数的最后一个预处理标记之后的空格被删除。 Otherwise, the original spelling of each preprocessing token in the argument is retained in the character string literal, except for special handling for producing the spelling of string literals and character literals: a \\ character is inserted before each " and \\ character of a character literal or string literal (including the delimiting " characters). 否则,参数中每个预处理标记的原始拼写都保留在字符串文字中,除了用于生成字符串文字和字符文字的拼写的特殊处理:在字符文字的每个“和\\”字符之前插入\\字符或字符串文字(包括分隔“字符”)。 If the replacement that results is not a valid character string literal, the behavior is undefined. 如果结果的替换不是有效的字符串文字,则行为未定义。 The character string literal corresponding to an empty argument is "". 对应于空参数的字符串文字是“”。 The order of evaluation of # and ## operators is unspecified. #和##运算符的求值顺序未指定。

And since 从那以后

16.3.1 Argument substitution 16.3.1参数替换

2 An identifier __VA_ARGS__ that occurs in the replacement list shall be treated as if it were a parameter, and the variable arguments shall form the preprocessing tokens used to replace it. 2替换列表中出现的标识符__VA_ARGS__应被视为它是一个参数,并且变量参数应形成用于替换它的预处理标记。

this is the same for varags as it is for normal parameters. 这对于varags和普通参数是一样的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM