Подтвердить что ты не робот

Препроцессор C переопределяет конфликт, зависящий от порядка включения

В проекте, над которым я работаю, я только что столкнулся с конфликтом переопределения, и, отслеживая, почему это не происходит на всех платформах (оказалось, что это касается порядка включений), я наткнулся на следующее поведение, которое я не могу объяснить.

1. компилируется без предупреждений

    #define LIST_HEAD(a) { int a = 0; }                                                                                                                     
    #include <sys/queue.h>                                                          

    int main() {                                                                    
        return 0;                                                               
    }

2. Предупреждение о макроопределении

    #include <sys/queue.h>
    #define LIST_HEAD(a) { int a = 0; }                                                                                                       

    int main() {                                                                    
        return 0;                                                               
    }

Я ожидал бы, что оба случая выдадут предупреждение, поскольку в <sys/queue.h> нет проверок, которые предотвратили бы переопределение.

Итак, почему первый случай не вызывает предупреждения, а второй? Что мне здесь не хватает?

Btw: Я получаю те же результаты на своем Mac с clang и моей Linux-коробкой с gcc.

4b9b3361

Ответ 1

По умолчанию это предупреждение подавляется в заголовках системы. Код в <sys/queue.h> считается полученным из системного заголовка, потому что sys/queue.h был найден путем поиска пути, помеченного как содержащий системные заголовки.

Итак, в (2) вы видите предупреждение, потому что оно генерируется внутри вашего кода, а в (1) предупреждение генерируется в queue.h и поэтому подавляется. Добавьте -Wsystem-headers к вашим параметрам компиляции, и вы увидите предупреждение в обоих случаях.