Pasting "-" does not give a valid preprocessing token
I'm porting a macro from VS to GCC. The macro is pretty trivial: Take A and B, and create "A-B":
Code:
#include <iostream>
#define QUOTE1(A) #A
#define QUOTE2(A, B) QUOTE1(A##-##B)
int main()
{
std::cout << QUOTE2(hello, world);
}
This works in VS, but GCC bans it, because it temporarily creates the token which is not a valid prepro token (apparently)
The workaround is pretty simple, instead of doing concat then quote, simply quote then concat:
Code:
#include <iostream>
#define QUOTE1(A) #A
#define QUOTE2(A, B) #A"-"#B
int main()
{
std::cout << QUOTE2(hello, world);
}
This works fine and all, but the "problem" is that it doesn't generate the *exact* same code as before:
Code:
std::cout << "hello-world"; //Before
std::cout << "hello""-""world"; //After
}
AFAIK, there should be no difference between the two approaches, but I need to be 100% sure I'm not breaking anything. I'm particularly worried about things like operator precedence. What exactly does the standard say about things like "A" "B" "C"? Are they, for all intents and purposes, as good as a single string, or are they a single string tied via a concatenation operator... ? Are there any risks if someone gets fancy embedding the macro inside chained operators (eg: ?:) ?
Or, would there be some pre-pro magic I do not know of that could generate my string with a single pair of double quotes?
Re: Pasting "-" does not give a valid preprocessing token
"a""b""c" and "abc" are the same literal string to the compiler. There is no concatenation "in code" happening here, the compiler will merge the strings into a single literal at compile time.
that doesn't mean there isn't any effect at all. There might be a noticable effect on compile time for one or the other if you have thousands of those in a compilation unit.
Re: Pasting "-" does not give a valid preprocessing token
according to the standard, the concatenation of string literals has its own translation phase (6th) occuring after macro expansion but before unit translation. So, at least standard-wise, they are equivalent with respect to code behavior, but they may be not with respect to macro expansion. For example,
Code:
#define A(X) #X
A("12") // expands to "\"12\""
A("1""2") // expands to "\"1\"\"2\""
regarding your use case, why can't you write just "#define QUOTE2(A, B) QUOTE1(A-B)" ?
Re: Pasting "-" does not give a valid preprocessing token
Quote:
Originally Posted by
superbonzo
according to the standard, the concatenation of string literals has its own translation phase (6th) occuring after macro expansion but before unit translation. So, at least standard-wise, they are equivalent with respect to code behavior, but they may be not with respect to macro expansion. For example,
Code:
#define A(X) #X
A("12") // expands to "\"12\""
A("1""2") // expands to "\"1\"\"2\""
Interesting. Good point.
Quote:
Originally Posted by
superbonzo
regarding your use case, why can't you write just "#define QUOTE2(A, B) QUOTE1(A-B)" ?
Ah... Now THERE is a good solution... Unfortunately, I gave you a reduced use case. Inside actual code, the "-" is (potentially) at call site:
Code:
std::cout << QUOTE2(hello, -world);