I was wondering how standard code complexity metrics (e.g., LOC, McCabe cyclomatic complexity, Halstead metrics, etc) are computed in the face of ifdefs in C/C++ code.
If ifdefs are ignored, syntax errors (or even type errors) may arise, such as in:
- #ifdef FOO
- for(i = 0; i < x; i++) {
- #else
- for(i = 0; i < y; i++) {
- #endif
- printf(...)
- }
If lines 1, 3 and 5 are ignored, the resulting code would have one loop inside the other, and a missing '}' (thus the syntax error).
If #ifdefs are taken into account, then one would need a single resulting measure per variant (in this case, one when FOO is defined, and another one for the case when FOO is not defined). However, such an approach can easily explode in practice.
Looking at http://manpages.ubuntu.com/manpages/natty/man1/pmccabe.1.html, the manpage reports that:
Parsing pmccabe ignores all cpp preprocessor directives - calculating the complexity of the appearance of the code rather than the complexity after the preprocessor mangles the code. This is especially important since simple things like getchar(3) expand into macros which increase complexity.
But, as I said, this approach may lead to code errors to appear, which in turn, may hinder the calculation process or result in an incorrect value.
How do tools overcome this problem (if they overcome at all)?
Regards.