查看: 285|回复: 0

[C/C++] 浅谈使用宏定义保护头文件

[复制链接]

0

技术

9

魅力

1

原创

版主

禁止访问

Rank: 7Rank: 7Rank: 7

积分
7734
人气
176
分享
52

最佳新人活跃会员

发表于 2023-8-17 21:37:36 | 显示全部楼层 |阅读模式
有时候,我们会在项目的头文件中看到如下代码:
[C] 纯文本查看 复制代码
#ifndef XXX
#define XXX
#endif

它的作用就是防止重复包含头文件
举个例子:
以下代码引用了两次test.h
[C] 纯文本查看 复制代码
//test.h
int testFunc()
{
    return 114514;
}

//test.c
#include "test.h"

#include "test.h"

int main()
{
    
}

编译:
[Shell] 纯文本查看 复制代码
gcc test.c -o homo

哦吼,报错了

In file included from .\test.c:3:
.\test.h:1:5: error: redefinition of 'testFunc'
    1 | int testFunc()
      |     ^~~~~~~~
In file included from .\test.c:1:
.\test.h:1:5: note: previous definition of 'testFunc' was here
    1 | int testFunc()
      |     ^~~~~~~~

简单分析一下就知道,是因为有两个个testFunc()
为什么会这样呢?
因为C/C++的引用头文件实际上就是把头文件写入到源文件中,由于引用了两次test.h,所以相当于定义了两侧testFunc
如果添加了最开头的代码呢?
[C] 纯文本查看 复制代码
#ifndef TEST_H
#define TEST_H
int testFunc()
{
    return 114514;
}
#endif

第一步,代码会变成这样:
[C] 纯文本查看 复制代码
#define TEST_H
int testFunc()
{
    return 114514;
}

后面再次判断时,由于TEST_H已经被定义,所以testFunc不会被定义第二遍
我们用gcc -E查看一下
[Shell] 纯文本查看 复制代码
gcc -E .\test.c > test.i

这是没有使用预编译指令的test.i
[C] 纯文本查看 复制代码
# 1 ".\\test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 ".\\test.c"
# 1 ".\\test.h" 1
int testFunc()
{
    return 114514;
}
# 2 ".\\test.c" 2

# 1 ".\\test.h" 1
int testFunc()
{
    return 114514;
}
# 4 ".\\test.c" 2

int main()
{

}

可以明显看到testFunc出现了两次
这是使用了预编译指令之后的
[C] 纯文本查看 复制代码
# 1 ".\\test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 ".\\test.c"
# 1 ".\\test.h" 1


int testFunc()
{
    return 114514;
}
# 2 ".\\test.c" 2



int main()
{

}

可以看到testFunc只有一次
小菜鸡一枚~
Gitee主页:https://gitee.com/juruoqwq
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表