Обрабатывает ли clang ++ системные заголовки более непринужденно? - PullRequest
0 голосов
/ 14 сентября 2018

В системном заголовочном файле 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 ++, которая обрабатывает системные заголовки более непринужденно?

1 Ответ

0 голосов
/ 14 сентября 2018

Есть ли какая-то магия в clang ++, которая обрабатывает системные заголовки более расслабленно?

Да, если мы посмотрим на документацию clang для управления диагностикой в ​​системеЗаголовки гласят:

Предупреждения подавляются, когда они появляются в системных заголовках .По умолчанию включенный файл обрабатывается как системный заголовок, если он найден в пути включения, заданном -isystem, но это можно изменить несколькими способами.

Прагму system_header можно использовать дляпометить текущий файл как системный заголовок.Предупреждения не будут выдаваться из местоположения прагмы и далее в том же файле.

#if foo
#endif foo // warning: extra tokens at end of #endif directive

#pragma clang system_header

#if foo
#endif foo // no warning

Аргументы командной строки –system-header-prefix= и –no-system-header-prefix= могут использоваться для переопределения того, являются ли подмножества пути включениярассматриваются как системные заголовки.Когда имя в директиве #include найдено в пути поиска заголовка и начинается с системного префикса, заголовок обрабатывается как системный заголовок.Последний префикс в командной строке, соответствующий указанному имени заголовка, имеет приоритет.

Например:

$ clang -Ifoo -isystem bar --system-header-prefix=x/ \
    --no-system-header-prefix=x/y/

Здесь #include "x/a.h" рассматривается как включающий системный заголовок, даже еслизаголовок находится в foo, а #include "x/y/b.h" считается не включающим системный заголовок, даже если заголовок находится в директиве bar.

#include, которая находит файл относительнотекущий каталог рассматривается как включающий системный заголовок, если включаемый файл обрабатывается как системный заголовок.

...