有効なヘッダーファイルを簡単に作成できるとはかぎりません。場合によっては、C と C++ の複数のバージョンで使用可能なヘッダーファイルを作成する必要があります。また、テンプレートを使用するためには、複数回の包含 (べき等) が可能なヘッダーファイルが必要です。
場合によっては、C と C++ の両方のプログラムにインクルード可能なヘッダーファイルを作成する必要があります。ただし、従来の C とも呼ばれる Kernighan & Ritchie C (K&R C) や、ANSI C、『Annotated Reference Manual』C++ (ARM C++)、および ISO C++ では、1 つのヘッダーファイル内の同一のプログラム要素について異なった宣言や定義が規定されていることがあります。言語とバージョンによる違いについての詳細は、『C++ 移行ガイド』を参照してください。これらのどの標準言語でもヘッダーファイルで使用できるようにするには、プリプロセッサマクロ __STDC__ や __cplusplus の定義の有無またはその値に基づいた条件付きコンパイルを使用する必要があります。
__STDC__ マクロは、K&R C では定義されていませんが、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
__cplusplus マクロは、C では定義されていませんが、C++ では定義されています。
__cplusplus マクロが定義されているかどうかを使用して、C と C++ を区別します。このマクロは、次のように関数宣言用の extern "C" インタフェースを保護するときに特に便利です。extern "C" の指定の一貫性を保つには、extern "C" のリンケージ指定のスコープ内には #include ディレクティブを含めないでください。
#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 { // ... };
ヘッダーファイルはべき等にするようにしてください。すなわち、同じヘッダーファイルを何回インクルードしても、1 回だけインクルードした場合と効果が同じになるようにしてください。このことは、テンプレートでは特に重要です。べき等を実現するもっともよい方法は、プリプロセッサの条件を設定し、ヘッダーファイルの本体の重複を防止することです。
#ifndef HEADER_H #define HEADER_H /* contents of header file */ #endif