名前空間
変種
操作

翻訳フェーズ

提供: cppreference.com
< cpp‎ | language
 
 
C++言語
一般的なトピック
フロー制御
条件付き実行文
繰り返し文 (ループ)
ジャンプ文
関数
関数宣言
ラムダ関数宣言
inline 指定子
例外指定 (C++20未満)
noexcept 指定子 (C++11)
例外
名前空間
指定子
decltype (C++11)
auto (C++11)
alignas (C++11)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点
文字 - 文字列 - nullptr (C++11)
ユーザ定義 (C++11)
ユーティリティ
属性 (C++11)
typedef 宣言
型エイリアス宣言 (C++11)
キャスト
暗黙の変換 - 明示的な変換
static_cast - dynamic_cast
const_cast - reinterpret_cast
メモリ確保
クラス
クラス固有の関数特性
特別なメンバ関数
テンプレート
その他
 
 

C++ のソースファイルは、以下のフェーズを正確にこの順序で行ったかのように、コンパイラによって処理されます。

目次

[編集] フェーズ1

1) ソースコードファイルの個々のバイトが基本ソース文字集合の文字に (処理系定義の方法で) マップされます。 特に、 OS 依存のファイル終端指示子が改行文字で置き換えられます。 基本ソース文字集合は以下の96個の文字から構成されます。
a) 5個のホワイトスペース文字 (スペース、水平タブ、垂直タブ、書式送り、改行)。
b) 10個の数字 ('0' から '9')。
c) 52個のアルファベット ('a' から 'z' および 'A' から 'Z')。
d) 29個の句読点文字 (_ { } [ ] # ( ) < > % : ; . ? * + - / ^ & | ~ ! = , \ " ')。
2) 基本ソース文字集合の文字にマップできないソースファイル中のあらゆる文字が、そのユニバーサル文字名 (\u または \U でエスケープされた) またはそれと同等に処理される何らかの処理系定義の形式に置き換えられます。
3) トライグラフシーケンスが対応する単一文字表現に置き換えられます。
(C++17未満)

[編集] フェーズ2

1) バックスラッシュが行末に現れた (直後に改行が続く) とき、バックスラッシュと改行の両方が削除され、2つの物理ソース行が1つの論理ソース行に結合されます。 これはシングルパスの操作です。 2個のバックスラッシュで終わる行末に空行が続いても、3つの行は1つに結合されません。 このフェーズでユニバーサル文字名 (\uXXXX) が形成された場合、動作は未定義です。
2) このステップの後、空でないソースファイルが改行文字で終わっていない場合 (元々改行がなかったか、バックスラッシュで終わっていたかのいずれか)、動作は未定義です (C++11未満)終端の改行文字が追加されます (C++11以上)

[編集] フェーズ3

1) ソースファイルがコメント、ホワイトスペース文字 (スペース、水平タブ、改行、垂直タブ、書式送り) の並び、および以下のいずれかであるプリプロセッシングトークンに分解されます。
a) <iostream>"myfile.h" などのヘッダ名。
b) 識別子
c) プリプロセッシング数値。
d) 文字および文字列リテラル (ユーザ定義リテラルを含みます) (C++11以上)
e) +<<=new<%##and などの、演算子および句読点 (代替トークンを含みます)。
f) その他のいかなるカテゴリにも収まらない個々の非ホワイトスペース文字。
2) あらゆる生文字列リテラルの、最初と最後のダブルクォートの間の、フェーズ1および2で行われたあらゆる変換が、取り消されます。
(C++11以上)
3) それぞれのコメントが1個のスペース文字に置き換えられます。

改行は維持されます。 改行でない非ホワイトスペースシーケンスが単一のスペース文字に折り畳まれるかどうかは未規定です。

入力が指定された文字までプリプロセッシングトークンにパースされた場合、次のプリプロセッシングトークンは、一般的には、たとえそれが後続の解析を失敗させるとしても、プリプロセッシングトークンを構成し得る最も長い文字の並びであるように取られます。 これは一般的に最長一致と呼ばれます。

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)"; // 生文字列リテラルと普通の文字列リテラル。
  • 次の3つの文字が <:: であり、後続の文字が : でも > でもない場合は、その < がそれ自体によるプリプロセッシングトークン (代替トークン <: の最初の文字ではなく) として扱われます。
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

1) プリプロセッサが実行されます。
2) #include 指令によって導入されたそれぞれのファイルに、フェーズ1から4が再帰的に適用されます。
3) このフェーズの終わりに、すべてのプリプロセッサ指令がソースから削除されます。

[編集] フェーズ5

1) 文字リテラルおよび文字列リテラル内のすべての文字が、ソース文字集合から実行文字集合 (少なくともフェーズ1に掲載されている基本ソース文字集合の96文字が含まれている限り、 UTF-8 のようなマルチバイト文字集合の場合もあります) に変換されます。
2) 文字リテラルおよび生でない文字列リテラル内のエスケープシーケンスおよびユニバーサル文字名が展開され、実行文字集合に変換されます。 ユニバーサル文字名によって指定された文字が実行文字集合のメンバでない場合、結果は処理系定義ですが、ヌル (ワイド) 文字とならないことは保証されます。

ノート: 処理系によっては、このステージで行われる変換はコマンドラインオプションによって制御できます。 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言語リファレンス