首页 > 为什么C/C++的预处理指令#include不自动让所包含的文件只包含一次?

为什么C/C++的预处理指令#include不自动让所包含的文件只包含一次?

在C/C++中#include所包含的头文件里面必须显式声明

#ifndef __HEADER_H_DEFINE__
#define __HEADER_H_DEFINE__

#endif

或者有些编译器支持

#pragma once

编译器完全有能力在执行预处理指令#include时使同一个文件只包含一次,但是却没有这么做,为什么?是否有需要包含同一个文件超过一次的情况?


1、C/C++ 的函数和变量都可以重复声明。条件判断是为了防止不必要的函数被声明,从而造成冲突。

他是为了避免重复编译,而不是解决重复声明。

2、#pragma once 同一个文件不会被编译多次。注意这里所说的 同一个文件 是指物理上的一个文件,而不是指内容相同的两个文件。

C/C++ 没有 Java 那种每个类对应一个文件的规定,所以即使使用了 #pragma once 也应该在头文件里面加上条件判断。


很多工程是有多次包含同一个头文件的需要的。原来看过flascc的头文件。某一个头文件被另一个包含了不下五次。一般是B中修改了宏定义然后包含A,再次修改宏定义再次包含A。


#include 不仅可以包含h文件, 包含其他类型文件也是可以的.
的确可以使得生成一个可执行文件包含同一个头文件多次, 我给题主举个拙劣的例子:

foo.h:

a = 43;

foo.c:

static int foo(void)
{
    int a;
#include "foo.h"
    return a;
}

int main(void)
{
    int a;
    int b;

#include "foo.h"
    b = foo();
    printf("a is %d, b is %d\n", a, b);
    return 0;
}

假如预处理器自动让头文件只包含一次, 那么变量a将得不到初始化.
在实际工程中还是可以见到把一些很庞大的数据放在一个文件, 然后 #include 这个文件的赋值给变量的.
另外也有 include 一个 c 文件的例子, 例如 redis.


还有一个作用,有些时候一个头文件会被其他头文件包含,比如
types.h 被header_a.h 和header_b.h包含,然后一个C文件同时包含header_a.h和header_b.h的时候,如果没有#ifdef/#define/#endif,那么types.h就会被包含两次,这样在types.h中typedef unsigned int uint32_t;之列的声明也会在同一个c文件中出现2次,编译器会曝出redefinition of typedef 'foobar‘ 之类的warning或者错误。

【热门文章】
【热门文章】