3

私はかなり長い間 C++ でプログラミングを行ってきましたが、今日までこれについて考えたことはありませんでした。

次のコードを検討してください。

struct foo
{
  // compiles fine
  void bar()
  {
    a = 1;
    my_int_type b;
    b = 5;
  }

  // Just a declaration, this fails to compile, which leads me to assume that
  // even though the bar() method is declared and defined all at once, the
  // compiler looks/checks-syntax-of the class interface first, and then compiles
  // the respective definitions...?
  void bar2(my_int_type); // COMPILE ERROR

  my_int_type       b; // COMPILE ERROR because it comes before the typedef declaration
  typedef int       my_int_type;
  my_int_type       a;

  void bar3(my_int_type); // compiles fine
};

int main()
{
  foo a;
  a.bar();
  return 0;
}

エラーが発生する理由(bar2()上記のコメントを参照)についての私の理解は正しいですか? いずれにせよ、シングルパス C++ コンパイラが上記のコードをコンパイルする方法の単純な概要を示した回答をいただければ幸いです。

4

3 に答える 3

10

ほとんどの場合、C++ ファイルは上から下に解析されるため、エンティティは使用する前に宣言する必要があります。

あなたのクラスでは、bar2とは、まだ宣言されていない をb使用しているため、無効です。my_int_type

"上から下へ" の構文解析規則の 1 つの例外は、クラスの定義内で定義されているメンバー関数です。このようなメンバー関数定義が解析されると、クラスの定義の後に現れたかのように解析されます。my_int_typeこれが、 inの使用法が有効である理由barです。

事実上、これは:

struct foo
{
    void bar()
    {
        my_int_type b;
    }

    typedef int my_int_type;
};

以下と同じです:

struct foo
{
    void bar();

    typedef int my_int_type;
};

inline void foo::bar()
{
    my_int_type b;
}
于 2012-06-06T23:09:29.603 に答える
5

コンパイラはブロック内でダウンし始めます。よく知られていないシンボルは、定義されていない新しいシンボルと見なされます。これは、関数定義またはヘッダー ファイルの背後にあるスキームです。

コンパイラーは最初に定義のリストを作成し、定義が以前に提供されているため、bar() メソッドが正しくコンパイルされるはずであると想定できます。

于 2012-06-06T23:08:57.983 に答える
3

それは可視性と多くの関係があります。あなたの混乱は、シングルパスを想定することから来るかもしれないと思います。クラスの解析は2段階で行われると考えてください。

  1. クラス定義を解析します。
  2. メソッドの実装を解析します。

これの利点は、クラスメンバー関数内からクラス全体を可視化できることです。

于 2012-06-06T23:26:05.300 に答える