创建有效的头文件是很困难的。头文件通常必须适应 C 和 C++ 的不同版本。要提供模板,请确保头文件能容纳多个包含(幂等)。
可能需要开发能够包含在 C 和 C++ 程序中的头文件。但是,称为“传统 C”的 Kernighan 和 Ritchie C (K&C)、ANSI C、 Annotated Reference Manual C++ (ARM C++) 以及 ISO C++ 有时要求一个头文件中同一个程序元素有不同的声明或定义。(有关语言和版本之间的变化的其他信息,请参见《C++ 迁移指南》。)要使头文件符合所有这些标准,可能需要根据预处理程序宏 __STDC__ 和 __cplusplus 的存在情况或其值来使用条件编译。
在 K&R C 中没有定义宏 __STDC__,但在 ANSI C 和 C++ 中都对其进行了定义。可使用该宏将 K&R C 代码与 ANSI C 或 C++ 代码区分开。该宏最适用于从非原型函数定义中区分原型函数定义。
#ifdef __STDC__ int function(char*,...); // C++ & ANSI C declaration #else int function(); // K&R C #endif
在 C 中没有定义宏 __cplusplus,但在 C++ 中对其进行了定义。
可使用 __cplusplus 宏的定义来区分 C 和 C++。该宏在保证为函数声明指定 extern “C” 接口时非常有用,如以下示例所示。为了防止出现 extern “C” 指定不一致,切勿将 #include 指令放在 extern “C” 链接指定的作用域中。
#include “header.h” ... // ... other include files... #if defined(__cplusplus) extern “C” { #endif int g1(); int g2(); int g3() #if defined(__cplusplus) } #endif
在预标准 (ARM) C++ 中,__cplusplus 宏的值为 1。在 ISO C++ 中,宏的值反映编译器所遵循的 C++ 标准的版本。值为标准的采用日期,如下所示:
C++ 1998/2003: 199711L C++ 2011: 201103L C++ 2014: 201402L (But see Notes)
对 Oracle Developer Studio 12.5 的说明:
不支持预标准 C++,因此宏从不会具有值 1。
仅部分支持 C++14,因此在 C++14 模式下宏具有 C++11 值 201103L。将来的发行版可能支持 C++14。
可以使用此宏的值来确定,在标准的更高版本中引入的构造在当前编译模式下是否可用。
例如,假定您要在类或虚拟函数上使用 "final" 限定符,但代码可能是在该功能不可用的 C++03 模式下编译的。您可以编写以下内容:
#if __cplusplus >= 201103L #define FINAL final #else #define FINAL #endif class A FINAL { // ... };
头文件应该具有幂等性,即,多次包括头文件的效果和仅包括一次的效果完全相同。该特性对于模板尤其重要。通过设置预处理程序条件以防止头文件体多次出现,可以很好的实现幂等。
#ifndef HEADER_H #define HEADER_H /* contents of header file */ #endif