Differences in the macro ## of the concatenation operator between Visual-C ++ and gcc

I have such a macro (not quite, but the function is completely equivalent):

#define STRUCTMEMBER(Member,Value) GlobalStructInstance. ## Member = Value ... STRUCTMEMBER(Item,1); 

This works fine in Visual C ++, but gcc 3.4.5 (MingGW) gives the following error:

insert "." and "Item" does not give a valid pre-processing token

This also happens when I use the "->" operator. I did not find hints of concatenation that the use of these operators is prohibited.

Does anyone have any ideas?

+5
gcc c-preprocessor visual-c ++ stringification
source share
3 answers

Perhaps Visual C ++ inserts a pair of spaces together to create another space. Not that spaces are tokens, but it will allow your code to work.

object.member not a token, it is three tokens, so you do not need to insert markers to implement the macro that you describe. Just remove '##' and it should work everywhere.

[Edit: just checked, and the result of using ## to form what is not a valid token is undefined. That way, the GCC can reject it, and the MSVC can ignore it and not execute paste, as far as I can tell.]

+7
source share

According to standard C, the result of the preprocessing operation " ## " must be a "preprocessing marker" or the result is undefined (C99 6.10.3.3 (3) - operator ##).

List of preprocessing tokens (C99 6.4 (3) - Lexical elements):

header names, identifiers, preprocessing numbers, character constants, string literals, punctuators, and single characters of non-white space that do not lexically correspond to other categories of preprocessor tokens.

GCC lets you know that you are entering undefined territory. MSVC is calmly pleased with the result of undefined (this is what you pretty much expect to expect).

Please note that if you still do not create any tokens, you do not need a marker gluing operator. In general (I'm sure there may be an exception or two), 2 tokens separated by spaces are equivalent to two tokens not separated by a space - as in your example.

+5
source share

From gcc c preprocessor docs :

However, two tokens that do not form a valid token cannot be inserted together.

struct.member is not one token.

In this case, you do not need to use the ## operator (concatenation token). You can simply delete it. Here is an example tested with gcc 4.2.4 on linux:

 #include <stdio.h> #define STRUCTMEMBER(Member, Value) GlobalStructInstance.Member = Value struct { const char* member1; }GlobalStructInstance; int main(void) { STRUCTMEMBER(member1, "Hello!"); printf("GlobalStructInstance.member1 = %s\n", GlobalStructInstance.member1); return 0; } 
+4
source share

All Articles