Menu

Include guards violating misra-c2012-2.5

2022-01-03
2023-02-10
  • Henrik Nyholm

    Henrik Nyholm - 2022-01-03

    Hi,
    I have a case where include guards in header files, e.g.

    #ifndef FOO_H
    #define FOO_H
    /* Contents of file */ 
    #endif //FOO_H
    

    will cause ccpcheck v2.6 to report the following:

    foo.h:2:0: [misra-c2012-2.5] Advisory: A project should not contain unused macro declarations #define FOO_H

    Do you think this is the correct behaviour? How does the tool interpret what 'unused' means in this context? It clearly has a purpose unlike a random macro that is not referenced in the code. This got me wondering what the MISRA guidelines actually say regarding include guards and I found MISRA C2012 Dir 4.10 (which gives the same example as above to show compliance):

    Precautions shall be taken in order to prevent the contents of a header file being included more than once

    Finally, it seems like include guards are not considered a violation if the header-file is included multiple times. I guess the logic is that the include guard is then actually used. However, it seems like very bad practice to only add include guards when you know you will include a header-file more than once, as this is very difficult to predict. Thus, if possible, I would like there to be some sort of exceptions to include guards with respects to misra-c2012-2.5 - thoughts on this?

     
  • Daniel Marjamäki

    Sorry for late reply!!

    I agree that we should try to avoid warnings for include guards.

     
  • Daniel Marjamäki

    hmm.. I can't reproduce directly..

    danielm@debian:~/cppcheck$ cat 1.c
    
    #include "foo.h"
    
    danielm@debian:~/cppcheck$ cat foo.h 
    #ifndef FOO_H
    #define FOO_H
    /* Contents of file */ 
    #endif //FOO_H
    
    danielm@debian:~/cppcheck$ ./cppcheck --addon=misra 1.c
    Checking 1.c ...
    danielm@debian:~/cppcheck$ 
    

    do you see the error with such code? maybe it has been fixed in git head?

     
  • Henrik Nyholm

    Henrik Nyholm - 2022-01-13

    Thanks for the reply!
    Could you please try with the following:

    foo.h:

    #ifndef FOO_H
    #define FOO_H
    /* Contents of file */ 
    #endif //FOO_H
    

    main.c:

    #include "foo.h"
    
    int main(void)
    {
    
    }
    

    and run ccpcheck on main.c ?

    I get:

    foo.h:2:0: [misra-c2012-2.5] Advisory: A project should not contain unused macro declarations #define FOO_H

     

    Last edit: Henrik Nyholm 2022-01-13
  • Henrik Nyholm

    Henrik Nyholm - 2022-01-19

    @danielmarjamaki have you had a chance to look at this yet? :)

    Thanks!

     
    • Daniel Marjamäki

      ah! Now I see the false positive. I have created ticket https://trac.cppcheck.net/ticket/10751

       
      👍
      1
  • José Martins

    José Martins - 2022-02-10

    I've been wandering myself if cppcheck should signal these macros as violations of rule 2.5 or not. My hesitation comes from the fact that although rule 2.5 does not explicitly open an exception for this case, directive 4.10 actually instructs us to avoid multiple inclusion of the same header, using exactly this form. Maybe this should just be considered a deviation and suppressed accordingly using inline annotations, citing directive 4.10 as the justification.

     

    Last edit: José Martins 2022-02-10
    • Henrik Nyholm

      Henrik Nyholm - 2022-02-11

      While rule 2.5 does not explicitly specify an exception for include guards, my opinion is that the wording of the rule effectively confirms that this is a false positive. The standard does not really specify what "unused" means. I would say that an include guard macro is not unused. It is used as an include guard.

      Moreover, if you look at the rationale:

      If a macro is declared but not used, then it is unclear to reviewer if the macro is redundant or has been left unused by mistake

      I would say that no reviewer would think it is unclear whether or not an include guard is redundant.

       

      Last edit: Henrik Nyholm 2022-02-11
      • José Martins

        José Martins - 2022-02-11

        That makes sense. The checker is then probably ignoring the use of the macro in conditional compilation expressions, no?

         

        Last edit: José Martins 2022-02-11
  • Henrik Nyholm

    Henrik Nyholm - 2022-02-16

    Hmm, I think the false positive only occurs if a header file is only included once.

    Anyway, I also managed to find this post on the misra forum where the official answer is that it is a false positive:
    https://forum.misra.org.uk/thread-1317.html

     
    • José Martins

      José Martins - 2022-02-17

      Anyway, I also managed to find this post on the misra forum where the official answer is that it is a false positive:
      https://forum.misra.org.uk/thread-1317.html

      It confirms your point!

      I think the false positive only occurs if a header file is only included once.

      From my tests this is not completely true. If I include the same header in two source files the false positive it's still there.

       
      👍
      1
  • Daniel Marjamäki

    I think this was fixed in cppcheck-2.8

     
  • Chris Coulson

    Chris Coulson - 2023-02-10

    Yes and no - if you test for your include guard with #ifndef FOO_H (as in the above examples) then all is well, however if you test with #if !defined(FOO_H) then it still false-positives

     

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.