是否有C ++标准库ifdef或ifndef预处理程序指令?

时间:2018-08-13 18:05:12

标签: c++ preprocessor standard-library

我正在用C ++构建自己的终端应用程序项目,我在问自己标准库是否包含ifdef或ifndef预处理程序指令。我想知道,因为我需要创建不同的头文件,而这些头文件需要一些标准的库头文件,例如“字符串”和其他一些文件头,因此我不想包含同一库3次或多次,因为它会使程序变重。 br /> 例如,我在我的头文件中写了这样的内容,以防止.h文件被多次包含:

#ifndef myheader_h
#define myheader_h
    // my file code here
#endif

我尝试编译,但是编译器对错误或警告一无所知。
我还尝试阅读标准库源代码(https://en.cppreference.com/w/cpp/header),但没有发现任何预处理程序规则,如ifdef或ifndef。
我应该包括这样的标准库头吗?

#ifndef string_h
#define string_h
    #include <string>
#endif

我希望我的问题没有被问到,因为我在搜索时没有找到它。

更新

对于有些人说“您无需担心”,而谁说“如果有适当的头卫,花费很少” ,我的意思是:程序的繁重很重要,我想使其更轻一些,所以我不想多次完全包含同一文件。标准lib文件有适当的包括防护措施吗? (我的头文件有它们,不知道std lib文件)

3 个答案:

答案 0 :(得分:5)

不需要标准头文件#define来定义任何特定的预处理器符号,以确保可以多次#include对其进行命名。

已经说过,任何明智的实现都将确保可以#include多次删除它们,而不会对应用程序代码产生不利影响。

结果证明,这是大多数标头(感谢@ Rakete1111)的标准要求。

C++ standard

  

翻译单元可以按任何顺序([lex])包含库头。每个元素都可以被包含一次以上,除了完全包含<cassert><assert.h>的效果每次都取决于NDEBUG的词法当前定义外,其效果与完全包含一次相同。

不仅如此,他们很有可能正在使用#pragma once指令。因此,即使您对同一标头多次使用#include,它们也只会被读取一次。

总而言之,不必担心标准头文件。如果您的头文件正确实现,那么您的应用程序就可以了。

答案 1 :(得分:1)

  

我问自己[sic]标准库是否包含ifdef或ifndef预处理程序指令

该标准没有指定是否有ifdef样式的标头保护符,尽管它确实要求以某种方式保护多重包含。我看了一下stdlibc ++标准库实现的随机标头。它确实具有标题保护。

  

我不想包含3次或多次相同的库,因为它会使程序更重

多次包含头文件不会使程序“变重”。

  

我应该包括这样的标准库头吗?

#ifndef string_h
#define string_h
    #include <string>
#endif

那不是必需的,或者特别有用。

答案 2 :(得分:1)

您正在谈论的那些预处理器指令称为“头保护器”,而标准库头肯定具有它们(或其他执行相同功能的机制),就像所有其他适当的头文件一样。多次包含它们不会造成任何问题,并且在编写自己的头文件时只需担心这些问题。

您正在阅读的“源代码”仅仅是说明头文件应如何工作的文档,但没有提供实际的代码。要查看代码,可以查看编译器提供的头文件。例如,Visual Studio中的<iostream>标头同时具有#pragma once和标头保护符:

#pragma once
#ifndef _IOSTREAM_
#define _IOSTREAM_
//...
#endif /* _IOSTREAM_ */

GCC编译器提供的标头还具有标头防护:

#ifndef _GLIBCXX_IOSTREAM
#define _GLIBCXX_IOSTREAM 1
//...
#endif /* _GLIBCXX_IOSTREAM */