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?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
I have a case where include guards in header files, e.g.
will cause ccpcheck v2.6 to report the following:
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):
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?
Sorry for late reply!!
I agree that we should try to avoid warnings for include guards.
hmm.. I can't reproduce directly..
do you see the error with such code? maybe it has been fixed in git head?
Thanks for the reply!
Could you please try with the following:
foo.h:
main.c:
and run ccpcheck on main.c ?
I get:
Last edit: Henrik Nyholm 2022-01-13
@danielmarjamaki have you had a chance to look at this yet? :)
Thanks!
ah! Now I see the false positive. I have created ticket https://trac.cppcheck.net/ticket/10751
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
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:
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
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
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
It confirms your point!
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.
I think this was fixed in cppcheck-2.8
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