2009-07-28 3 views
5

問題は2つの異なるファイルに2つの列挙型があり、同じセットの定数が必要です。他のファイルと)。列挙型を同期させたい、つまり、ある列挙型が列挙型に新しい値を追加し、他の列挙型を更新することを忘れた場合、コンパイルエラーをスローしたい。それは可能ですか?Cプログラム - コンパイル時に2つの列挙型が同期しているかどうかを調べる

答えて

11

なぜこの宣言を1つのヘッダーファイルに入れて、それを2つの場所に含める必要はありませんか?

+0

コンパイル時にこのようなことができるかどうかを知りたいです。 –

+0

私が知る限り、コンパイル時には不可能です。 gcc(またはあなたが使っているもの)を呼び出す前に、コーパスの前にプリプロセッサを書いて実行することができます。このプリプロセッサは、両方のファイルを生成し、一方を他方から生成する。 – Gregor

+0

@Gregor、hmmm。コンパイル自体を開始する前に、関連宣言の複数のコピーを別々のフェーズとして生成することができます。 –

5

各列挙型は、LAST_ENUM_1やLAST_ENUM_2などの既知の列挙型で終了している必要があります。両方のヘッダーファイルにアクセスできるファイルで#ifを使用して比較します。列挙型で使用

#if LAST_ENUM_1 != LAST_ENUM_2 
    #error Enums have different sizes 
#endif 
+0

+1いいアイデア。 '#error'のようなものがあるのを知らなかった。 – Gregor

+0

#errorは標準の一部だと思います。通常は#ワーニング(または類似)もありますが、C標準の一部ではありません。 – Robert

+0

プリプロセッサで使用できる列挙定数の値はありますか? 私はそうではないと思うので、最終チェックは実行時に行わなければならないでしょう... – Tobi

0

名は、明確である必要があり、あなたは問題があるでしょう:どちらかのコンパイラは、両方の定義にアクセスすることが、その後、列挙型が原因の名前の問題やコンパイラで同じにすることはできません1つの定義にしかアクセスできない場合は、チェックすることはありません。

(Robertによって提案されたように)要素の数さえコンパイル時にチェックすることはできません(プリプロセッサは列挙型について何も知らない)。本当に1つの共通ヘッダーファイルを持つことができない場合は、アプリケーションの開始時にランタイムチェックを行うのが最も簡単です。

0

あなたはその形式のように使用している場合は、多分あなたは私は本当に私が今sugestます1よりも良い他の回答のように...

+1

私は '= 3'を最後に付けません。なぜなら、それは列挙型を追加するときに変更する必要があるからです。 – Robert

1

簡単にすべてを処理することができます

enum EMyEnum 
{ 
    JOE = 0, 
    BLACK = 1, 
    WHITE = 2, 

    END_OF_ENUM = 3 
} 

などの使用

他のすべてのソリューションがうまくいかない場合は、同じものかどうかをチェックする単純なperlスクリプトを作成し、makefileからperlスクリプトが呼び出されていることを確認してください。 これで問題は解決しますが、できれば回避してください。

0

コンパイラは一度に1つのソースファイル(トランスレーションユニット、TU)を調べるので、現在のTUとそれが見ていない他のいくつかのTUの間の不一致について不平を言う方法はありません。

両方のプログラムで使用される列挙型定義のコピーが1つあるように修正する必要があります。そのため、両方のプログラムで使用されるヘッダーに含まれています。他の何もかもが、あまりにもエラーを起こしやすくなります。

関連する問題