12

私が取り組んでいるプロジェクトで再定義の競合が発生しました。なぜそれがすべてのプラットフォームで発生しないのか (インクルードの順序であることが判明しました) を追跡しているときに、説明できない次の動作に遭遇しました。

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>再定義を防ぐチェックがないため、両方のケースで警告が生成されると予想されます。

では、最初のケースでは警告が表示されないのに、2 番目のケースでは表示されるのはなぜでしょうか? ここで何が欠けていますか?

ところで:clangを使用したMacとgccを使用したLinuxボックスで同じ結果が得られます。

4

1 に答える 1

14

デフォルトでは、この警告はシステム ヘッダーで抑制されます。のコードは、システム ヘッダーを含むとマークされたパスを検索してsys/queue.h<sys/queue.h>が見つかったため、システム ヘッダーに由来すると見なされます。

したがって、(2) ではコード内で生成されるため警告が表示されますが、(1) では警告はqueue.h内で生成されるため抑制されます。コンパイル オプションに追加-Wsystem-headersすると、どちらの場合も警告が表示されます。

于 2012-12-16T16:44:27.893 に答える