Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Differences in Macro ## concatenation operator between Visual-C++ and gcc

I'm having a macro like this ( not exactly, but function is quite equivalent):

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

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

pasting "." and "Item" does not give a valid preprocessing token

This also happens when I use the "->" operator. I didn't found hints on concatenation, that the usage of these operators is forbidden.

Does anyone have an idea ?

like image 393
Florian Storck Avatar asked Jul 30 '09 13:07

Florian Storck


2 Answers

Maybe Visual C++ is pasting a couple of spaces together to make another space. Not that whitespaces are tokens, but it would allow your code to work.

object.member is not a token, it's three tokens, so you don't need token-pasting to implement the macro you describe. Just remove the '##' and it should work everywhere.

[Edit: just checked, and the result of using ## to form something that isn't a valid token is undefined. So GCC is allowed to reject it and MSVC is allowed to ignore it and perform no paste, as far as I can tell.]

like image 115
Steve Jessop Avatar answered Sep 23 '22 13:09

Steve Jessop


According to the C Standard, the result of the '##' preprocessing operator must be a 'preprocessing token' or the result is undefined (C99 6.10.3.3(3) - The ## operator).

The list of preprocessing tokens is (C99 6.4(3) - Lexical elements):

header names, identifiers, preprocessing numbers, character constants, string literals, punctuators, and single non-white-space characters that do not lexically match the other preprocessing token categories.

GCC lets you know that you're entering undefined territory. MSVC is silently happy with the undefined result (that is what you'd pretty much expect to happen).

Note that if you're not creating a single token anyway, then you don't need the token pasting operator. Generally (I'm sure there's probably an exception or two), 2 tokens separated by whitespace is equivalent to 2 tokens not separated by whitespace - as in your example.

like image 41
Michael Burr Avatar answered Sep 19 '22 13:09

Michael Burr