Oracle® Solaris Studio 12.4: C++ ユーザーズガイド

印刷ビューの終了

更新: 2014 年 12 月
 
 

11.7.5 標準ヘッダーの実装

C には、<stdio.h><string.h><stdlib.h> などの 17 個の標準ヘッダーがあります。これらのヘッダーは Oracle Solaris オペレーティングシステムの一部として提供され、/user/include にあります。C++ にも同様のヘッダーがありますが、さまざまな宣言の名前が大域名前空間と std 名前空間の両方に存在するという要件が付加されています。

また、C++ には、C 標準ヘッダー (<cstdio><cstring><cstdlib> など) のそれぞれについても専用のバージョンがあります。C++ 版の C 標準ヘッダーでは、宣言名は std 名前空間にのみ存在します。C++ には、32 個の独自の標準ヘッダー (<string><utility><iostream> など) も追加されています。

標準ヘッダーの実装で、C++ ソースコード内の名前がインクルードするテキストファイル名として使用されているとしましょう。たとえば、標準ヘッダーの <string> (または <string.h>) が、あるディレクトリにある string (または string.h) というファイルを参照するものとします。この実装には、次の欠点があります。

  • ヘッダーファイルにファイル名接尾辞 (拡張子) がない場合に、ヘッダーファイルのみを検索すること、またはヘッダーファイルに関する規則を示す makefile を作成することができない。

  • string というディレクトリまたは実行可能プログラムがあると、そのディレクトリまたはプログラムが標準ヘッダーファイルの代わりに検出される可能性がある。

こうした問題を解決するため、コンパイラの include ディレクトリには、ヘッダーと同じ名前を持つファイルと、 一意の接尾辞 .SUNWCCh を持つ、そのファイルへのシンボリックリンクが含まれています。 SUNW はコンパイラに関係するあらゆるパッケージに対する接頭辞、CC は C++ コンパイラの意味、.h はヘッダーファイルの通常の接尾辞です。つまり <string> と指定された場合、コンパイラは <string.SUNWCCh> と書き換え、その名前を検索します。接尾辞付きの名前は、コンパイラ専用の include ディレクトリにだけ存在します。このようにして見つけられたファイルがシンボリックリンクの場合 (通常はそうである)、コンパイラは、エラーメッセージやデバッガの参照でそのリンクを 1 回だけ間接参照し、その参照結果 (この場合は string) をファイル名として使用します。ファイルの依存関係情報を送るときは、接尾辞付きの名前の方が使用されます。

この名前の書き換えは、2 つのバージョンがある 17 個の標準 C ヘッダーと 32 個の標準 C++ ヘッダーのいずれかを、パスを指定せずに山括弧 < > で囲んで指定した場合にだけ行われます。山括弧の代わりに引用符が使用されるか、パスが指定されるか、ほかのヘッダーが指定された場合、名前の書き換えは行われません。

次の表は、よくある書き換え例をまとめています。

表 11-3  ヘッダー検索の例
ソースコード
コンパイラによる検索
注釈
<string>
string.SUNWCCh
C++ の文字列テンプレート
<cstring>
cstring.SUNWCCh
C の string.h の C++ 版
<string.h>
string.h.SUNWCCh
C string.h
<fcntl.h>
fcntl.h
標準 C および C++ ヘッダー以外
"string"
string
山括弧ではなく、二重引用符
<../string>
../string
パス指定がある場合

コンパイラが header.SUNWCCh (header はヘッダー名) を見つけられない、コンパイラは、#include ディレクティブで指定された名前で検索し直します。たとえば、#include <string> というディレクティブを指定した場合、コンパイラは string.SUNWCCh という名前のファイルを見つけようとします。この検索が失敗した場合、コンパイラは string という名前のファイルを探します。

11.7.5.1 標準 C++ ヘッダーの置き換え

標準ヘッダーの実装で説明している検索アルゴリズムのため、Installing the Replacement Libraryで説明している 代替ライブラリのインストール バージョンの代替 ヘッダーを指定する必要はありません。ただし、記載されているいくつかの問題が発生した場合、推奨される解決方法は、接尾辞が付いていないヘッダーごとに、接尾辞 .SUNWCCh を持つシンボリックリンクを追加することです。つまり、ファイルが utility の場合、次のコマンドを実行します。

example% ln -s utility utility.SUNWCCh

utility.SUNWCCh というファイルを探すとき、コンパイラは 1 回目の検索でこのファイルを見つけます。そのため、utility という名前のほかのファイルやディレクトリを誤って検出してしまうことはありません。

11.7.5.2 標準 C ヘッダーの置き換え

標準 C ヘッダーの置き換えはサポートされていません。それでもなお、独自のバージョンの標準ヘッダーを使用する場合、推奨される手順は次のとおりです。

  • すべての代替ヘッダーを 1 つのディレクトリに置きます。

  • そのディレクトリ内にある代替ヘッダーごとに header.SUNWCCh (header はヘッダー名) へのシンボリックリンクを作成します。

  • コンパイラを呼び出すごとに -I 指令を指定して、代替ヘッダーが置かれているディレクトリが検索されるようにします。

たとえば、<stdio.h><cstdio> の代替ヘッダーがあるとします。stdio.hcstdio をディレクトリ /myproject/myhdr に置きます。このディレクトリ内で、次のコマンドを実行します。

example% ln -s stdio.h stdio.h.SUNWCCh
example% ln -s cstdio cstdio.SUNWCCh

コンパイルのたびに、オプション -I/myproject/mydir を使用します。

警告:
  • C ヘッダーを置き換える場合は、対になっているもう一方のヘッダーを置き換える必要があります。たとえば、<time.h> を置き換える場合は、<ctime> も置き換えるようにしてください。

  • 代替ヘッダーは、置き換える前のヘッダーと同じ効果を持っている必要があります。これは、さまざまな実行時ライブラリ (libCrunlibClibCstd、および libc) が標準ヘッダーの定義を使用して構築されているためです。同じ効果を持っていない場合、作成したプログラムはほとんどの場合、正しく動作しません。