-
April 24th, 2013, 04:06 AM
#1
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?
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
April 24th, 2013, 10:32 AM
#2
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.
-
April 24th, 2013, 10:39 AM
#3
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)" ?
Last edited by superbonzo; April 24th, 2013 at 10:46 AM.
-
April 25th, 2013, 10:13 AM
#4
Re: Pasting "-" does not give a valid preprocessing token
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.
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);
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|