翻訳フェーズ
C++ のソースファイルは、以下のフェーズを正確にこの順序で行ったかのように、コンパイラによって処理されます。
フェーズ1
'0' から '9')。'a' から 'z' および 'A' から 'Z')。_ { } [ ] # ( ) < > % : ; . ? * + - / ^ & | ~ ! = , \ " ')。\u または \U でエスケープされた) またはそれと同等に処理される何らかの処理系定義の形式に置き換えられます。|
3) トライグラフシーケンスが対応する単一文字表現に置き換えられます。
|
(C++17未満) |
フェーズ2
\uXXXX) が形成された場合、動作は未定義です。フェーズ3
<iostream> や "myfile.h" などのヘッダ名。|
2) あらゆる生文字列リテラルの、最初と最後のダブルクォートの間の、フェーズ1および2で行われたあらゆる変換が、取り消されます。
|
(C++11以上) |
改行は維持されます。 改行でないホワイトスペースの並びが単一のスペース文字に折り畳まれるかどうかは未規定です。
入力が指定された文字までプリプロセッシングトークンにパースされた場合、次のプリプロセッシングトークンは、一般的には、たとえそれが後続の解析を失敗させるとしても、プリプロセッシングトークンを構成し��る最も長い文字の並びであるように取られます。 これは一般的に最長一致と呼ばれます。
int foo = 1;
int bar = 0xE+foo; // エラー、無効なプリプロセッシング数値 0xE+foo。
int baz = 0xE + foo; // OK。
int quux = bar+++++baz; // エラー、 bar++ + ++baz ではなく bar++ ++ +baz です。
最長一致ルールの唯一の例外は以下の通りです。
#define R "x"
const char* s = R"y"; // ill-formed な生文字列。 "x" "y" ではありません。
const char* s2 = R"(a)" "b)"; // 生文字列リテラルと普通の文字列リテラル。
struct Foo { static const int v = 1; };
std::vector<::Foo> x; // OK、 <: は [ に対する代替トークンとしては取られません。
extern int y<::>; // OK、 extern int y[] と同じです。
int z<:::Foo::value:>; // OK、 int z[::Foo::value]; と同じです。
|
(C++11以上) |
- ヘッダ名のプリプロセッシングトークンは
#include指令の中でのみ形成されます。
std::vector<int> x; // OK、 <int> はヘッダ名ではありません。
フェーズ4
フェーズ5
ノート: 処理系によっては、このステージで行われる変換はコマンドラインオプションによって制御できます。 gcc および clang はソース文字集合のエンコーディングを指定するために -finput-charset を使用し、エンコーディングプレフィクスを持たない (C++11以上)文字列および文字リテラル内の実行文字集合のエンコーディングを指定するために -fexec-charset および -fwide-exec-charset を使用します。 Visual Studio 2015 Update 2 およびそれ以降はソース文字集合および実行文字集合を指定するためにそれぞれ /source-charset および /execution-charset を使用します。
フェーズ6
隣接する文字列リテラルが連結されます。
フェーズ7
コンパイルが行われます。 それぞれのプリプロセッシングトークンがトークンに変換されます。 これらのトークン列は構文的および意味的に解析され、1個の翻訳単位として翻訳されます。
フェーズ8
要求されるテンプレートの実体化 (明示的実体化によって要求されるものを含みます) のリストを生成するために、それぞれの翻訳単位が調べられます。 テンプレートの定義が検索され、実体化単位を生成するために、要求される実体化が行われます。
フェーズ9
翻訳単位、実体化単位、および外部参照を満たすために必要なライブラリ部品が、その実行環境での実行のために必要な情報を含むプログラムイメージ内に収集されます。
ノート
コンパイラによっては、実体化単位 (テンプレートリポジトリまたはテンプレートレジストリとも言います) を実装せず、単にフェーズ7で各テンプレートの実体化をコンパイルし、そのコードを、それを暗黙または明示的に要求したオブジェクトファイル内に格納し、その後、リンカがフェーズ9でそれらのコンパイル済み実体化をひとつに折り畳みます。
参考文献
- C++11 standard (ISO/IEC 14882:2011):
- 2.2 Phases of translation [lex.phases]
- C++98 standard (ISO/IEC 14882:1998):
- 2.1 Phases of translation [lex.phases]
関連項目
翻訳フェーズ の C言語リファレンス
|