Menu

Can't get cppcheck working with token pasting

2021-04-27
2021-04-29
  • Joseph McLaughlin

    I can't seem to get cppcheck (v1.90) to recognize my build macro that uses token pasting, though gcc has no problem with it. Here is some test code:

    #include <cstdio>
    
    // Offending macro with token pasting:
    #define IS_DEFINED(name)  (defined(__ ## name ## __))
    
    #define __FOO__ 1
    
    #if IS_DEFINED(FOO)
    int function1() {
      int inside_function1 = 0;
      return 0;
    }
    #endif
    
    #if defined(__FOO__)
    int function2() {
      int inside_function2 = 0;
      return 1;
    }
    #endif
    
    int main() {
      printf("test_token_parsing: function1() = %d\n", function1());
      printf("test_token_parsing: function2() = %d\n", function2());
      return 0;
    }
    

    When i compile and run this with gcc (ubuntu v9.3.0) I see the expected output from both functions:

    # gcc test_token_pasting.cpp; ./a.out
    test_token_parsing: function1() = 0
    test_token_parsing: function2() = 1
    

    But when I run cppcheck:

    # cppcheck --enable=all test_token_pasting.cpp 
    Checking test_token_pasting.cpp ...
    test_token_pasting.cpp:17:24: style: Variable 'inside_function2' is assigned a value that is never used. [unreadVariable]
      int inside_function2 = 0;
                           ^
    nofile:0:0: information: Cppcheck cannot find all the include files (use --check-config for details) [missingIncludeSystem]
    

    It doesn't see the unreadVariable error inside function1()--the one wrapped in the macro defined with IS_DEFINED(FOO) that uses token-pasting. How do I make this work?

     
    • Daniel Marjamäki

      I would claim that you have undefined behavior in your code.

      http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf

      In chapter 6.10.1 , item 4, (page 148) it says:

      If the token defined is generated as a result of this replacement process or use of the defined unary operator does not match one of the two specified forms prior to macro replacement, the behavior is undefined.

      But well I guess it would be good if we were more clear about it.

      And I am not against that we try to "handle" this like gcc/clang.. A goal of Cppcheck is that it will be possible to analyze code that does not strictly follow the C standard.

       
    • Daniel Marjamäki

      I would like that a issue is created in the simplecpp issue tracker. Do you have a github account? https://github.com/danmar/simplecpp/issues
      You can reduce your code example so it only demonstrates that the preprocessing is different to gcc/clang.

       
  • Joseph McLaughlin

    I moved the issue here to the simplecpp github repo as requested.

    I've made a very hacky workaround where I first apply a patch to the code in the third-party library replacing each instance of the offending macro with equivalent code. Then I run cppcheck. When it completes I reverse the patch to get things back to where they were. Hopefully this is not the permanent solution, but it may be.

     
  • Daniel Marjamäki

    ah ok yes that is quite a hack.

    For information it would likely be better to utilize --library that will give Cppcheck a better understanding of the 3rd-party library... not just the compiler interface but also the semantics. But I guess it's a big job to provide the necessary configuration..

    i.e. I have seen this construct in easylogging and we don't have a easylogging configuration yet.

     
    👍
    1

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.