头文件重复包含
问题:如何发生的
// a.h
typedef struct { int x; } A;
// b.h
#include "a.h"
// main.c
#include "a.h"
#include "b.h" // a.h 被展开第二次 → A 重复定义 → 编译报错
预处理阶段 #include 就是文本复制粘贴。同一个 .h 被多链条引入时,里面的定义出现在翻译单元中 ≥2 次,编译器报重复定义。
⚠️ 函数/变量声明重复没事,但
typedef、struct定义、宏等重复就会炸。
解决 1:#ifndef 守卫(传统/跨平台)
// a.h
#ifndef A_H
#define A_H
typedef struct { int x; } A;
#endif第一次包含时:
#ifndef A_H:预处理器检查——“A_H这个标志被定义过吗?” → 没有。#define A_H:预处理器说”好,那我现在定义它!”typedef struct { int x; } A;:头文件里的真正内容被正常展开,送到编译器去编译。#endif:条件结束。
第二次包含时:
#ifndef A_H:预处理器再次检查——“A_H这个标志被定义过吗?” → 刚才已经定义过了!- 跳过内容:条件不成立,预处理器直接删掉/跳过从
#ifndef到#endif之间的所有代码。
结果:第二次包含在编译期变成”一片空白”,代码自然就不会被定义两次了。
命名约定:文件名_H(大写),或用 项目_模块_文件名_H 避免同库冲突。
解决 2:#pragma once(简洁/非标准但主流编译器都支持)
// a.h
#pragma once
typedef struct { int x; } A;一行搞定:编译器认得这个文件,下次再 #include 直接跳过。