[英]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.