搜索

首页  >  问答  >  正文

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

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

#ifndef __HEADER_H_DEFINE__
#define __HEADER_H_DEFINE__

#endif

或者有些编译器支持

#pragma once

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

大家讲道理大家讲道理2804 天前950

全部回复(4)我来回复

  • 黄舟

    黄舟2017-04-17 11:17:45

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

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

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

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

    回复
    0
  • 怪我咯

    怪我咯2017-04-17 11:17:45

    #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.

    回复
    0
  • PHP中文网

    PHP中文网2017-04-17 11:17:45

    还有一个作用,有些时候一个头文件会被其他头文件包含,比如
    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或者错误。

    回复
    0
  • 巴扎黑

    巴扎黑2017-04-17 11:17:45

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

    回复
    0
  • 取消回复