Clang ++ более спокойно обрабатывает системные заголовки?

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

C99 - это не C++, а тем более C++ 17

Rich 14.09.2018 04:31

Я знаю, поэтому ожидаю предупреждения в C++ 17.

xmllmx 14.09.2018 04:31

Ах, мои извинения. Всю ночь читаю вопросы новичков: - /

Rich 14.09.2018 04:41
clang.llvm.org/docs/… "Предупреждения подавляются, когда они появляются в системных заголовках. По умолчанию включенный файл рассматривается как системный заголовок, если он находится в пути включения, указанном параметром -isystem, но это можно изменить несколькими способами.
Rich 14.09.2018 04:46

Интересно, что я не вижу его так определено здесь, хотя там он является гибким элементом массива.

Shafik Yaghmour 14.09.2018 04:54

Обратите внимание, что __flexarr - зарезервированный идентификатор.

n. 1.8e9-where's-my-share m. 14.09.2018 08:39

@ShafikYaghmour: Некоторые компиляторы до C99 требуют использования [0] для достижения семантики «рассматривать пространство за структурой как часть массива», некоторые компиляторы требуют использования [], некоторые будут одинаково хорошо работать с любым из них, а некоторые не могут обрабатывать такая семантика у всех. Если ожидается, что код будет использоваться только с компилятором, который принимает одну конкретную синтаксическую форму, нет необходимости пытаться обрабатывать обе.

supercat 01.10.2018 18:49
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
7
644
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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_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 warning

The –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 in foo, and #include "x/y/b.h" is treated as not including a system header, even if the header is found in bar.

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.

Другие вопросы по теме