簡體   English   中英

與預處理器指令混淆

[英]Confusion with Preprocessor Directives

我有三個檔案

文件“ grandparent.h”

#ifndef GRANDPARENT_H
#define GRANDPARENT_H

struct foo {
    int member;
};

#endif /* GRANDPARENT_H */

文件“ parent.h”

#include "grandparent.h"

文件“ child.c”

 #include "grandparent.h"
 #include "parent.h"

維基說

在此,“ grandparent.h”的第一個包含將導致定義宏GRANDPARENT_H。 然后,當“ child.c”第二次包含“ grandparent.h”時,#ifndef測試返回false,並且預處理器跳至#endif,從而避免了對struct foo的第二個定義。 程序正確編譯。

Q1。 ““ grandparent.h”的第一個包含將導致 GRANDPARENT_H 被定義 “,所以我了解我基本上定義了一個名為GRANDPARENT_H的宏,但我不明白的是,該宏的內容(即GRANDPARENT_H)將如何被包括在孩子中c。

我們只是在定義宏GRANDPARENT_H,即

#define GRANDPARENT_H

struct foo {
    int member;
};

但是它的內容如何

struct foo {
    int member;
};

被包括在孩子中

如果您手動“擴展” child.c ,直到沒有#include為止:

//grandparent.h

#ifndef GRANDPARENT_H    // <- not defined at this point
#define GRANDPARENT_H    // <- now it's defined

struct foo {
    int member;
};

#endif /* GRANDPARENT_H */
//parent.h

//#include "grandparent.h" resolves into
//grandparent.h

#ifndef GRANDPARENT_H   // <- already defined, skip until matching #endif
#define GRANDPARENT_H   // <- not executed by preprocessor

struct foo {            // <- not provided to the compiler
    int member;
};

#endif /* GRANDPARENT_H */

現在按順序閱讀。 第一行檢查是否定義了宏GRANDPARENT_H 顯然不是,因為它是代碼的第一條指令。

第二行定義GRANDPARENT_H宏。 它是空的,但這並不重要,重要的是已定義它。

然后,代碼定義了您的結構...

當預處理器遇到第二個#ifdef GRANDPARENT_H ,宏已經定義好了,因此它將跳過文件的全部內容,並且不會出現任何foo redefined錯誤。

使用-E選項確認是否可以看到預處理的child.c文件:

$ gcc -E child.c
# 1 "child.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "child.c"
# 1 "grandparent.h" 1


struct foo {
    int member;
};
# 2 "child.c" 2
# 1 "parent.h" 1
# 2 "child.c" 2

如您所見,該結構僅定義一次。

請注意,現在大多數編譯器都支持一種更簡單的方法:只需插入

#pragma once

在文件的開頭。 像這樣:

#pragma once

struct foo {
    int member;
};

而已!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM