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