[英]Confusion with Preprocessor Directives
I have three files 我有三个档案
File "grandparent.h" 文件“ grandparent.h”
#ifndef GRANDPARENT_H
#define GRANDPARENT_H
struct foo {
int member;
};
#endif /* GRANDPARENT_H */
File "parent.h" 文件“ parent.h”
#include "grandparent.h"
File "child.c" 文件“ child.c”
#include "grandparent.h"
#include "parent.h"
Wiki says 维基说
Here, the first inclusion of "grandparent.h" causes the macro GRANDPARENT_H to be defined.
在此,“ grandparent.h”的第一个包含将导致定义宏GRANDPARENT_H。 Then, when "child.c" includes "grandparent.h" the second time, the #ifndef test returns false, and the preprocessor skips down to the #endif, thus avoiding the second definition of struct foo.
然后,当“ child.c”第二次包含“ grandparent.h”时,#ifndef测试返回false,并且预处理器跳至#endif,从而避免了对struct foo的第二个定义。 The program compiles correctly.
程序正确编译。
q1. Q1。 "the first inclusion of "grandparent.h" causes the macro GRANDPARENT_H to be defined ", So what i understand i its basically defining a macro named
GRANDPARENT_H
but what i dont understand is that how will the content of that macro (ie GRANDPARENT_H) would be included in the child.c. ““ grandparent.h”的第一个包含将导致宏 GRANDPARENT_H 被定义 “,所以我了解我基本上定义了一个名为
GRANDPARENT_H
的宏,但我不明白的是,该宏的内容(即GRANDPARENT_H)将如何被包括在孩子中c。
We are just defining the macro GRANDPARENT_H ie 我们只是在定义宏GRANDPARENT_H,即
#define GRANDPARENT_H
struct foo {
int member;
};
but how will its content ie 但是它的内容如何
struct foo {
int member;
};
be included in the child.c 被包括在孩子中
If you "expand" child.c
manually until there are no #include
left: 如果您手动“扩展”
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 */
now read it sequentially. 现在按顺序阅读。 The first line checks if macro
GRANDPARENT_H
is defined. 第一行检查是否定义了宏
GRANDPARENT_H
。 Obviously it is not, as it's the first instruction of the code. 显然不是,因为它是代码的第一条指令。
The second line defines GRANDPARENT_H
macro. 第二行定义
GRANDPARENT_H
宏。 It's empty but that's no important, what's important is that it is defined . 它是空的,但这并不重要,重要的是已定义它。
Then, the code defines your struct... 然后,代码定义了您的结构...
When the preprocessor encounters the second #ifdef GRANDPARENT_H
, the macro is already defined, so it skips the whole contents of the file and you don't get any foo redefined
error. 当预处理器遇到第二个
#ifdef GRANDPARENT_H
,宏已经定义好了,因此它将跳过文件的全部内容,并且不会出现任何foo redefined
错误。
Which is confirmed by using -E
option to see preprocessed child.c
file: 使用
-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
as you can see, the structure is only defined once. 如您所见,该结构仅定义一次。
Note that most compilers now support a simpler way to do this: just insert 请注意,现在大多数编译器都支持一种更简单的方法:只需插入
#pragma once
at the start of your file. 在文件的开头。 Like this:
像这样:
#pragma once
struct foo {
int member;
};
that's it! 而已!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.