Mixed C/C++ Project: SonarLint applying C++ rules to C headers

Please provide

  • Operating system: Windows
  • Visual Studio version: 17.8.7
  • SonarLint plugin version: 7.6.3.83110
  • Programming language you’re coding in: C and C++
  • Is connected mode used: Yes
    • Connected to SonarCloud or SonarQube (and which version): SonarQube - Developer Edition - Version 9.9.4 (build 87374)

And a thorough description of the problem / question:

I have a mixed C/C++ project. I was having the issue discussed here: Mixed C/C++ Project: C++ rules applied to included C headers. I was able to fix it on the SonarQube side by splitting analysis into 2 scans/projects (C and C++ scans). I now have 2 sonar-project.properties files: one for C and one for C++. Each properties file contains exclusions for the other language (i.e. C properties excludes .cpp/.hpp and viceversa).

However, SonarLint in Visual Studio is reporting C++ issues on a C header file. SonarQube report doesn’t show any issues. How can I make SonarLint use SonarQube reported issues?

Hi,

Welcome to the community!

To be clear, you have two projects on SonarQube for the same repository?

You’re in connected mode. Which project are you connected to? The C project of the C++ project?

 
Thx,
Ann

Hi Ann,

Yes, 2 project on SonarQube for the same repository.

Good point. I didn’t think of which project it’s bound to. At the moment, it’s bound to to the C++ project. Is there.

What’s the best course of action with this?

Thanks,
Joan

Hi Joan,

Hmm… actually, connected mode should have applied the exclusion settings from your C++ project, so it should be completely ignoring the C header files (.h I assume?).

Can you double-check your file suffixes per language: Project Settings → General Settings → Languages → C / C++ / Objective-C. It looks to me like the defaults correctly split files across languages, but maybe you have something different?

 
Ann

Hi Ann,

Yes, C files are named .c/.h and C++ are named .cpp/.hpp. The properties files have sonar.exclusions=**/*.c,**/*.h (C++ props) and sonar.exclusions=**/*.cpp,**/*.hpp (C props). SonarQube has the default settings as in the snippet you show above.

Joan

Hi Joan,

You’re setting your exclusions in your properties file. You said that to start with. :woman_facepalming:

Things set in analysis properties are not persisted to the server.

If you had set those exclusions through the UI, then SonarLint would be able to pick them up.

 
Ann

Hi Ann,

I just realized I can set those properties per project and not just globally. I can see the file is ignored in the SonarLint log.

Now, is it possible to have SonarLint flag C issues in .h files and C++ issues in .hpp? Can SonarLint bind to 2 projects?

Thanks,
Joan

Hi @joanpereyra,

I assume you are using Visual Studio in solution mode.
While exclusion/inclusion is synchronized from the server, the language of a header file is detected from the vcxproj setting. Here is an explanation of how to change it to C: C project parsed with C++ rules - #3 by Abbas

This allows you to force the language of header files per vcxproj.

Side note:

  • I don’t think having two projects on SonarQube is ideal. If the analysis is triggering a C++ issue on a .h file, it means the .h file was included in a source file compiled as C++ according to the build-wrapper JSON.

  • If this is the case, and you still want to keep this file C compliant, I expect that you wrap the code with extern C in case __cplusplus.

  • Since the post, we improved our C++ rules to not trigger in extern C context. If they did when you analyzed your codebase in one project, I invite you to post the rules that were triggered on this forum and we will treat them as false-positive and fix them.

3 Likes

Hi @Abbas,

Thank you for your suggestion. I will try this soon. I’ve been busy with something else at the moment. Please don’t close the thread yet.

Thanks,
Joan

Hi @Abbas,

I agree having 2 projects on SonarQube is not ideal. I’d like to have a single project if possible. Right now, I’m testing a project where the C++ header is .hpp and C header is .h.

The main.cpp includes both header files, but does use extern “C” wrapped by __cplusplus.

I just realized we trigger SonarQube scans from Linux. At the moment, we generate coverage report on Linux with CMake and gcovr. For this reason, the scan is performed from a Linux request. The build-wrapper is generated using cmake. Do you have any suggestions for CMake?

Thanks,
Joan

Hi @joanpereyra,
I’m not sure I understand the question. Are you talking about SonarQube or VisualStudio Cmake mode? and how is your question related to OS(Linux)/Build tool(CMake)/ or coverage(gcovr)?
Thanks,

Hi @Abbas,

We are developing for both Windows and Linux. We use MsBuild and Visual Studio on Windows and GCC and CMake for Linux. Code coverage reports are generated on Linux only using gcovr. SonarQube analysis is called from Linux only using sonar-scanner and the generated build-wrapper. I’m don’t know if SonarQube would be aware of the Visual Studio project if the analysis is not executed from Windows. In other words, would any setting found in the Visual Studio project affect the scan and SonarLint?

Again, we are definitely wrapping .h files (C headers) with extern "C and __cplusplus #ifdef.

With this in mind, how can SonarQube differentiate between a C header and a C++ header?

Thanks,
Joan

Hi @joanpereyra,

What is synchronized between SonarQube and SonarLint are general scanning settings(enabled rules, rules setting, excluded files), not specific C&C++ analysis settings.
Analysis settings come from build-wrapper in SonarQube context and Visual Studio in the SonarLint context. You can find the synchronized settings here: Connected Mode - Visual Studio

With that in mind, language detection in VS is separate from SonarQube.

In the previous answer, I explained how we detect header language in SonarLint VisualStudio.

In SonarQube, we analyze source files that are compiled in your build-wrapper command.
The language of the source file is deduced from the captured compiler command line arguments in the Build-wrapper JSON the same way your compiler decides on which language to use.
Header files are analyzed in the context of source files where they are included:

  • if a header file is only included in a C source file → it is analyzed as C
  • if a header file is only included in a C++ source file → it is analyzed as C++
  • if a header file is not included in any compiled source file → it is not analyzed
  • if a header file is included in both C and C++ source files → it is analyzed as C and as C++. Even if a header file is analyzed as C++, we are incrementally improving our C++ rules to not trigger in the extern C context.

Thanks,