В заголовочном файле системы Linux /usr/include/sys/inotify.h определена следующая структура:
struct inotify_event
{
int wd;
uint32_t mask;
uint32_t cookie;
uint32_t len;
char name __flexarr;
};
Обратите внимание на последнее поле name, который представляет собой массив нулевой длины. C++ 17 не поддерживает массивы нулевой длины, поэтому при использовании struct inotify_event в проекте C++ 17 и его компиляции с помощью -pedantic должно появиться предупреждение компилятора.
Однако следующий код не вызывает никаких предупреждений для struct inotify_event. Что еще более странно, если я определяю структуру с использованием массива нулевой длины таким же образом, предупреждение возникает, как и ожидалось.
Параметры компилятора: 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()
{}
Есть ли какая-то магия за clang ++, которая более расслабленно обращается с системными заголовками?
Я знаю, поэтому ожидаю предупреждения в C++ 17.
Ах, мои извинения. Всю ночь читаю вопросы новичков: - /
Интересно, что я не вижу его так определено здесь, хотя там он является гибким элементом массива.
Обратите внимание, что __flexarr - зарезервированный идентификатор.
@ShafikYaghmour: Некоторые компиляторы до C99 требуют использования [0] для достижения семантики «рассматривать пространство за структурой как часть массива», некоторые компиляторы требуют использования [], некоторые будут одинаково хорошо работать с любым из них, а некоторые не могут обрабатывать такая семантика у всех. Если ожидается, что код будет использоваться только с компилятором, который принимает одну конкретную синтаксическую форму, нет необходимости пытаться обрабатывать обе.





Is there any magic behind clang++ that treats system-defined headers in a more relaxed way?
Да, если мы посмотрим на clang документация по управлению диагностикой в заголовках системы, он говорит:
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_headerpragma 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#includedirective 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
#includedirective 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.
C99 - это не C++, а тем более C++ 17