Menu

preprocessor problem with ## ?

Martin
2021-02-12
2021-02-17
  • Martin

    Martin - 2021-02-12

    Hi,

    analyzing the following code

    #define VSTR2(n1, n2, n3)           n1 ## . ## n2 ## . ## n3
    VersionInfo_t vpVersion = {VSTR2(1,2,3)};
    

    with

    ./cppcheck -v --enable=information file.cpp

    returns:

    file.cpp:1:0: error: failed to expand 'VSTR2', Invalid ## usage when expanding 'VSTR2'. [preprocessorErrorDirective]
    #define VSTR2(n1, n2, n3)    n1 ## . ## n2 ## . ## n3
    

    The compiler accepts the code.
    Could you please check?

    Thanks,
    Martin

     
  • Daniel Marjamäki

    I can reproduce.

    I don't remember exactly how/why I implemented this in this way.

    I have the feeling that this code is undefined behavior. The spec (i.e. https://eel.is/c++draft/cpp.concat) says "If the result is not a valid preprocessing token, the behavior is undefined.". And I guess 1.2.3 is not a valid preprocessing token?

    But then the output from Cppcheck is very confusing. Especially that the error id is "preprocessorErrorDirective".

     
  • Martin

    Martin - 2021-02-15

    Mh I couldn't find any (other) source about preprocessor token naming which supports either side, but in our SW the code (reliably) does what it should and it can be compiled.

    The error also comes up with:

    VersionInfo_t vpVersion = {VSTR2(a,2,3)};
    

    And I'd guess a.2.3 is a valid token?

    It looks like cppcheck rejects characters like . and - in the token, replacing . with _ works for example.

     
  • Daniel Marjamäki

    could you show a compilable code example? either with 1.2.3 or with a.2.3?

     
  • Daniel Marjamäki

    Even if it is undefined behavior I would prefer to make it gcc compatible. But then some portability warning would be good to have.

     
  • Martin

    Martin - 2021-02-15

    Mh cutting out the original code into a sample file does indeed generate this error:
    main.cpp:41:28: error: pasting "VP_VERNUMBER_1" and "." does not give a valid preprocessing token
    Sorry, I assumed the code above was built as part of our daily builds, but in fact the file seems to be obsolete (and quite old) :-|

     
  • Daniel Marjamäki

    ok thanks for investigating.. it seems cppcheck is not entirely wrong then but if there is some special case that gcc handles differently I think it would make sense to handle it in cppcheck also..

    and the error message should be clarified.

     

    Last edit: Daniel Marjamäki 2021-02-15
  • Paul Fultz

    Paul Fultz - 2021-02-16

    VSTR2(1,2,3) is valid because it understood to concat to one number. However, VSTR2(a,2,3) is rejected by clang and gcc(which do have conforming C preprocessors):

    error: pasting formed 'a.', an invalid preprocessing token
    

    Because a.2 is not a valid token.

     
    • Daniel Marjamäki

      VSTR2(1,2,3) is valid because it understood to concat to one number.

      I can understand that 1.2 is a number but I do not understand that it thinks that 1.2.3 is a valid number token? I can also see that VSTR2(1,2,3) is allowed by the gcc preprocessor but the number 1.2.3 generates a syntax error.

      do you have some compilable code that we should support?

      Maybe if the result is directly converted to a string? But there is still UB so I think a warning would be good.

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.