The following struct is defined in the Linux system header file /usr/include/sys/inotify.h
:
struct inotify_event { int wd; uint32_t mask; uint32_t cookie; uint32_t len; char name __flexarr; };
Please note the last field name
, which is a zero-length array. C++17 does not support zero-length array, so, if using struct inotify_event
in a C++17 project and compiling it with -pedantic
, a compiler warning should be raised.
However, the following code doesn’t raise any warning for struct inotify_event
. More weird, if I define a struct using zero-length array the same way, the warning is raised as expected.
Compiler options: clang++ -std=c++17 -pedantic main.cpp
#include <sys/inotify.h> struct inotify_event* p = nullptr; // no warning struct A { int x; char name __flexarr; // warning: flexible array members are a C99 feature }; int main() {}
Is there any magic behind clang++ that treats system headers in a more relaxed way?
Advertisement
Answer
Is there any magic behind clang++ that treats system-defined headers in a more relaxed way?
Yes, if we look at the clang documentation for Controlling Diagnostics in System Headers it says:
Warnings are suppressed when they occur in system headers. By default, an included file is treated as a system header if it is found in an include path specified by
-isystem
, but this can be overridden in several ways.The
system_header
pragma can be used to mark the current file as being a system header. No warnings will be produced from the location of the pragma onwards within the same file.#if foo #endif foo // warning: extra tokens at end of #endif directive #pragma clang system_header #if foo #endif foo // no warningThe
–system-header-prefix=
and–no-system-header-prefix=
command-line arguments can be used to override whether subsets of an include path are treated as system headers. When the name in a#include
directive is found within a header search path and starts with a system prefix, the header is treated as a system header. The last prefix on the command-line which matches the specified header name takes precedence.For instance:
$ clang -Ifoo -isystem bar --system-header-prefix=x/ --no-system-header-prefix=x/y/Here,
#include "x/a.h"
is treated as including a system header, even if the header is found infoo
, and#include "x/y/b.h"
is treated as not including a system header, even if the header is found inbar
.A
#include
directive which finds a file relative to the current directory is treated as including a system header if the including file is treated as a system header.