2016-09-14 4 views
2

sizeofがコンパイル時の演算子であるかを評価します。 See heresizeof演算子は、コンパイルのどの段階でgcc

コンパイルには多くの段階があります。 sizeofオペレータがどの段階で評価されていますか?

+0

? –

+3

プリプロセッサを実行した後(プリプロセッサは 'sizeof'を認識しません)、オブジェクトファイルがアセンブラで作成されるかリンクされて実行可能ファイルが生成される前に評価されますので、メイン 'コンパイラ'で評価されます。プリプロセッサとコンパイラとアセンブラ(実際にはリンカ)はすべて1つのプログラムでも、複数のプログラムでもかまいません。標準は気にしない。例外はVLA可変長配列のサイズです。コンパイル時ではなく、実行時に評価する必要があるかもしれません。 –

+0

@JonathanLeffler答えとして投稿する必要があります。 – Lundin

答えて

3

典型的には、プリプロセッサの実行後と前処理された翻訳単位(全ヘッダ#includeの代わりに貼り付けられたファイル、すべての場所で置換#define年代、#ifdef条件文の非アクティブな分岐が完全に除去、等)、コンパイラを生成します走る現代のコンパイラは、通常は前処理も可能ですが、歴史上の理由から、Cプリプロセッサ(cpp)とCコンパイラ(cc)は、少なくとも概念的に異なるものです。前者の出力は後者への入力として働く。

この段階では、これらの段階が何であるか、そしてその順序が何であるかは、完全にコンパイラの内部実装に依存します。しかし、最も伝統的なパイプラインは次のとおりです。

  • レクシング:互いにトークンを分離します。
  • 構文解析:言語文法に従ってトークンの組み合わせを解釈し、構文解析ツリーを生成する。
  • 抽象構文木の生成:構文解析木が入力として使用され、より有用でより良い注釈付き木が生成されます。
  • スコープ解析:使用された識別子をそれぞれの宣言と照合し、宣言されていない識別子の場合はエラーを出力します。
  • タイプチェック:各式のタイプが特定のコンテキスト内の予想タイプと一致するかどうかをチェックします。この段階が終了し、エラーが発生していない場合、プログラムは構文的にも意味的にも正しいとみなされますので、次の手順に進むことができます。
  • コード生成と最適化:おそらくこの段階では、コンパイラは、sizeof(int)を表す抽象ノードの代わりに、たとえば4を出力します。また、3 + 4のような定数式を7に噛み砕くでしょう。

sizeofは場合に実行時に評価されることに注意してください可変長配列(以降C99)に適用されます。すべては「コンパイル」の状態とは何

int n; 
n = ...; 
int vl_arr[n]; 
sizeof(vl_arr); // could be evaluated at runtime if "n" is not known at compile-time 
関連する問題