【发布时间】:2013-11-13 08:37:14
【问题描述】:
我想知道windows.h、math.h、iostream、stdio...等文件中是否包括保护措施。
因为我在不同的文件中多次包含这些标题。这些文件是否已经内置了保护程序或者是否定义了定义?
我只是想知道这类事情的标准是什么。
【问题讨论】:
-
你可以用编辑器打开那些头文件并检查吗?
标签: c++ include-guards
我想知道windows.h、math.h、iostream、stdio...等文件中是否包括保护措施。
因为我在不同的文件中多次包含这些标题。这些文件是否已经内置了保护程序或者是否定义了定义?
我只是想知道这类事情的标准是什么。
【问题讨论】:
标签: c++ include-guards
如果您打开文件来读取内容(您甚至可以在大多数编辑器中右键单击包含指令来打开文件),您会看到包含文件通常以以下内容开头:
#ifndef _WINDOWS_
#define _WINDOWS_
...
所以第一次进入文件,因为_WINDOWS_没有定义,所以它会被定义,文件的内容会被包含进去。第二次#ifndef 将失败,因为之前已完成定义。
这是放置安全措施的标准方法,许多编译器支持的另一种方法是放置#pragma once。例如,如果有人在另一个文件中定义相同的常量,这有利于防止冲突。
【讨论】:
这些文件位于/usr/include/ 和子目录中(至少在我的 debian 笔记本电脑上)。看着/usr/include/stdio.h
展示了一个典型的后卫,
#ifndef _STDIO_H
# define _STDIO_H 1
并检查 cpp,grep __cplusplus,
#if !defined __cplusplus || defined __STDC_LIMIT_MACROS
...
【讨论】:
许多编译器支持#pragma once。所有标准库都已经具有#pragma once 或适当的预处理器宏形式的保护。您可以在the Wikipedia page 上了解更多关于守卫的信息。确定的最快方法是右键单击包含文件定义并要求开发环境(Visual Studio/Eclipse)打开该文件。然后你会看到守卫。
【讨论】:
C++ 标准要求对标头进行组织,以便您可以直接或间接地多次包含其中的任何一个,而不会遇到问题。它没有规定如何实现这一结果,只是规定应该实现。
17.6.2.2 标头 [using.headers]
¶2 翻译单元可以以任何顺序包含库头(第 2 条)。每个都可以被包含多次,与只包含一次没有任何不同,除了包含
<cassert>或<assert.h>的效果每次都取决于NDEBUG的词汇当前定义。178178 这与标准 C 库相同。
【讨论】: