Complexity Metrics not being applied to #if #ifdefs

Please provide

  • Operating system: Windows 11 Pro
  • SonarQube for VS Code plugin version: v4.15.0
  • Programming language you’re coding in: C++
  • Is connected mode used: No
    • SonarQube Cloud, SonarQube Server, or SonarQube Community Build? (if one of the latter two, which version?):

And a thorough description of the problem / question:

I’ve been experimenting with C++ complexity metrics (Cognitive and Cyclomatic Complexity) in SonarQube. During my tests, I noticed that preprocessor directives such as #ifdef, #if, and other macros are not being considered when calculating these metrics.

Here are some screenshots from VS Code with the ErrorLens extension, demonstrating the issue:


I also tried to search about this topic but I coudn’t find anything conclusive…

Is this behavior intentional, or is it a limitation of the current implementation? I ask because the SonarQube team has discussed macros and preprocessors in C/C++, yet the original Cognitive Complexity white paper states:

Cognitive Complexity assesses structural increments for:
• Loop structures: for, while, do while, …
• Conditionals: ternary operators, if, #if, #ifdef, …

Hi,

Welcome to the community, and very well spotted!

To be honest you’re the first person to have raised this (that I’m aware of).

So first, I should mention that cxx is not offered or maintained by SonarSource. Our C++ analyzer is closed-source.

Regarding our implementation, what you’ve observed is a limitation of where we were technically at the time. When the rule was initially implemented for C++, we were working - on the analyzer side - with the output of the build wrapper. By the time we were examining the code, the preprocessor directives had already been executed away and weren’t available to the analyzer.

We made a mental note of the limitation and released the rule and the metric.

In the years since, we’ve evolved to the point that we could probably handle this properly, but it’s not clear when (if) there will be time to do that.

If we’re able to take this up, it’s possible (likely?) that we’ll add an exception to the spec, since it seems harsh to apply a nesting increment to everything in an #ifdefed method. That would be informed by a sanity-check cycle between iteration and specification.

And a final note on the language: My point in this:

was partly to explicitly include preprocessor directives, and partly to make clear that it doesn’t matter how your language spells if and elif; it’s the functionality that matters, and they’re all included.

 
HTH,
Ann

2 Likes

Thanks for the explanation. :smiling_face:

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.