简体   繁体   English

Visual C ++与gcc / clang的不同行为,同时对包含逗号的参数进行字符串化

[英]Different behavior in visual c++ versus gcc/clang while stringifying parameter which contains comma

I'm using stringizing operator to convert parameter which may contains comma passed to a macro into string. 我正在使用字符串运算符将可能包含传递给宏的逗号的参数转换为字符串。 As I know, some characters cannot be stringified – notably, the comma(,) because it is used to delimit parameters and the right parenthesis()) because it marks the end of the parameter. 据我所知,某些字符无法进行字符串化-特别是逗号(,),因为它用于定界参数,而右括号()),因为它标记了参数的结尾。 So I use a variadic macro to pass commas to the stringizing operator like this: 因此,我使用可变参数宏将逗号传递给字符串运算符,如下所示:

#include <stdio.h>

#define TEST 10, 20

#define MAKE_STRING(...)  #__VA_ARGS__
#define STRING(x)       MAKE_STRING(x)

int main()
{
    printf("%s\n", STRING(TEST) );
    return 0;
}

it works fine. 它工作正常。 But it occurs to me what would happen without variadic macro, so I modify the macro: #define MAKE_STRING(x) #x . 但是它发生在我身上,如果没有可变参数宏,将会发生什么事情,所以我修改了宏: #define MAKE_STRING(x) #x It compiles fine unexpectedly in visual c++ 2008/2010, and output 10, 20 while gcc/clang give the compilation error as expected: 它在Visual c ++ 2008/2010中意外编译良好,并输出10, 20而gcc / clang给出了预期的编译错误:

macro "MAKE_STRING" passed 2 arguments, but takes just 1 宏“ MAKE_STRING”传递了2个参数,但只接受了1个

So my question: is the Visual c++ doing additional work or the behavior is undefined? 所以我的问题是:Visual c ++是在做其他工作还是行为未定义?

VS in general allows extra parameters in macros and then just drops them silently: STRING(10, 20, 30) - still works and prints 10 . VS通常允许在宏中添加额外的参数,然后将其静默删除: STRING(10, 20, 30) -仍然有效并打印10 This is not the case here, but it pretty much means VS don't even have the error gcc threw at you. 这里不是这种情况,但这在很大程度上意味着VS甚至没有向您抛出gcc错误。

It's not any additional work but "merely" a difference in substitution order. 这不是任何额外的工作,而是“仅”替换顺序上的差异。

I am not sure if this will answer your question but i hope this will help you solving your problem. 我不确定这是否能回答您的问题,但我希望这会帮助您解决问题。 When defining a string constant in C, you should include it in double quotes (for spaces). 在C中定义字符串常量时,应在双引号中将其包括(用于空格)。 Also, the # macro wrap the variable name inside double quotes so, for example, #a become "a" . 同样, #宏将变量名用双引号引起来,例如, #a变为"a"

#include <stdio.h>

#define TEST "hello, world"
#define MAKE_STRING(x) #x

int main()
{
    int a;
    printf("%s\n", TEST);
    printf("%s\n", MAKE_STRING(a));
    return 0;
}

I compiled this code using gcc 4.7.1 and the output is: 我使用gcc 4.7.1编译了此代码,输出为:

hello, world
a

I dunno why this has upvotes, or an answer got downvoted (so the poster deleted it) but I don't know what you expect! 我不知道为什么这会投票赞成,或者答案被投票反对(所以海报将其删除了),但我不知道您期望什么!

#__VA_ARGS__ makes no sense, suppose I have MACRO(a,b,c) do you want "a,b,c" as the string? #__VA_ARGS__没有任何意义,假设我有MACRO(a,b,c)您想要“ a,b,c”作为字符串吗?

http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html#Variadic-Macros http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html#Variadic-Macros

Read, that became standard behaviour, variable length arguments in macros allow what they do in variable length arguments to functions. 读取(已成为标准行为)后,宏中的可变长度参数允许它们在函数的可变长度参数中进行操作。 The pre-processor operates on text! 预处理器对文本进行操作!

The only special case involving # is ##, which deletes a comma before the ## if there are no extra arguments (thus preventing a syntax error) 涉及#的唯一特殊情况是##,如果没有多余的参数,它将删除##之前的逗号(从而防止语法错误)

NOTE: 注意:

It is really important you read the MACRO(a,b,c) part and what do you expect, a string "a,b,c"? 阅读MACRO(a,b,c)部分非常重要MACRO(a,b,c)您期望字符串“ a,b,c”是什么呢? or "a, b, c" if you want the string "a, b, c" WRITE THE STRING "a, b, c" 或“ a,b,c”(如果您想要字符串“ a,b,c”)写字符串“ a,b,c”

Using the # operator is great for stuff like 使用#运算符非常适合诸如

#define REGISTER_THING(THING) core_of_program.register_thing(THING); printf("%s registered\n",#THING);

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

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