Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

clang-tidy: How to suppress C++ warnings in C header file?

I've got a .h file that is included by both C and C++ source files. Its contents is wrapped in

#ifdef __cplusplus
extern "C" {
#endif

...

#ifdef __cplusplus
}
#endif

Yet, when I include it in a .cpp file, clang-tidy issues C++-specific messages, like

  • warning: including 'stdbool.h' has no effect in C++; consider removing it [hicpp-deprecated-headers,modernize-deprecated-headers]
  • warning: inclusion of deprecated C++ header 'stdlib.h'; consider using 'cstdlib' instead [hicpp-deprecated-headers,modernize-deprecated-headers]
  • warning: use 'using' instead of 'typedef' [modernize-use-using]

I like these checks and I want to keep them active in my clang-tidy configuration, but of course for C++ code only. I can't change the header file to use using instead of typedef or <cstdlib> instead of <stdlib.h> because it's also included by C sources, hence the extern "C".

Is there any way to tell clang-tidy to treat code in extern "C" as C instead of C++, even if included from a .cpp file?

The clang-tidy version is 12.0.0.

like image 520
Wolfram Rösler Avatar asked Jun 21 '21 09:06

Wolfram Rösler


1 Answers

Clang-Tidy can make use of the special NOLINT or NOLINTNEXTLINE comments to suppress warning of specific lines. It is intended exactly for your use case:

  • some lines contains legacy or not stricly nice C++ code
  • there is a good reason to do so - here the code has to be parseable by a C compiler.

The higher risk when using that is to abuse it and silence warnings where it would have be possible to improve the coding. But when you need a header to be used form both C and C++ sources, and you have carefully twice read the NOLINTed line, it is perfectly fine, at least IMHO. Furthermore, it is even possible to indicate the warnings to silence:

#ifdef __cplusplus
extern "C" {
#endif
// NOLINTNEXTLINE(hicpp-deprecated-headers,modernize-deprecated-headers) C compatible code
#include <stdbool.h>
#include <stdlib.h>     // NOLINT C code requires that header
...

#ifdef __cplusplus
}
#endif
like image 66
Serge Ballesta Avatar answered Oct 07 '22 01:10

Serge Ballesta