CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    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
    Code:
    hello-world
    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.

  2. #2
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    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.

  3. #3
    Join Date
    Oct 2008
    Posts
    1,456

    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.

  4. #4
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: Pasting "-" does not give a valid preprocessing token

    Quote Originally Posted by superbonzo View Post
    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 View Post
    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
  •  





Click Here to Expand Forum to Full Width

Featured