2

このクラスは私のプロジェクトで定義されました:

class B : public A
{
 public:
 A& Get_a(int type);

 ...
 protected:
 #ifdef COMPILE_FLAG
 int line_num;
 const char* file_name;
 #endif
 ...
 private:
 int int_value;
 bool bool-val;
};

関数Get_aは次のように実装されます (関連する部分のみを配置します)。

A& B::Get_a(int type)
    {
     B* returned_a = B->Get_val(type);
     return *(A*)(returned_a) ;
    }

これは、このクラスを使用するコードです。

{
...
B b_val;
A* a_val = &b_val->Get_a(5);
...
}

私のコードは、クラス A と B がコンパイルされる DLL とは異なる DLL にコンパイルされます。私の DLL はフラグ COMPILE_FLAG でコンパイルされませんが、A、B の DLL はこのフラグでコンパイルされます。コードが別の B クラスから変換しようとしても、コンパイル エラーは発生しませんでした。コードの実行中に、a_valガベージ フィールド値がありました。実際にシフトされた値。

C++ コンパイラがこのバグについて警告しなかった理由と、これらの定義を改善するためのコーディングのヒント#ifdef(これらのフィールドはログに使用されると知らされました) についての説明が欲しいです。

編集:同じ名前の 2 つのクラスを記述する場合、各クラスは異なる dll に含まれます。次に、それらの間の参照を作成すると、コンパイル エラーが発生します。プリプロセッサはコンパイラの前に実行されるため、コンパイラはこのクラスの再定義をチェックできます。

4

3 に答える 3

5

#ifdefプリプロセッサ ディレクティブです。前処理は、コンパイルの最初の部分として実行されます。通常の C++ 構文を前処理した後でのみ、有効にする必要があり、チェックすることができます。

あなたは1 つの定義規則#ifdefに違反しています:異なる翻訳単位に (異なるサイズの)クラスの 2 つの異なる定義があります。コンパイラはこれを検出できません。結論として、これはあなたのコードのバグだと思います。コーディングのヒントとして、すべてのファイルを同じコンパイラ設定でコンパイルすることをお勧めします。この特定のケースでは、.B#ifdef

于 2013-06-18T06:46:34.793 に答える