0

構造体のメンバーを複数回宣言することに対するCの規則は、警備員を含めることが必要である主な理由であるように私には思えます。「header.h」に次のものがある場合:

struct s {
    int a;
    char b;
};

また、ファイル「ah」#includeのheader.hの場合、struct sが2回定義されているため、「ah」と「header.h」の両方を含めることはできません。

私の質問は、これを行うことの問題は何ですか?構造体の複数の同一の定義を許可できないのはなぜですか?これにより、インクルードガードが不要になり、Cヘッダーファイルが大幅にクリーンアップされます。

Cの規則では、複数の宣言が許可されていますが、定義は1つだけです。何らかの理由で、構造体のメンバーを指定することは、変数や関数を定義していなくても、「定義」と呼ばれます。

4

3 に答える 3

1

構造体の再定義は、非常にエラーが発生しやすいものです。あなたの単純な例でも、#pragma「header.h」を含める前に構造体のパッキングまたは配置を調整する a が ah に含まれている場合、2 つの定義は必ずしも同じであるとは限りません。このタイプの問題は、ヘッダーのインクルード順序に依存するため、デバッグが困難です。

一般に、データ型の再定義を許可すると、問題が発生する可能性があることがいくつかあります。代わりに、ヘッダー ガードを削除できる以外に、実際のメリットはありません。ヘッダー ガードは問題を解決し、コードを不当に乱雑にしないマイナー レベルのオーバーヘッドにすぎません。一部のコンパイラ#pragma onceは、インクルード ガードとして機能する (または類似の) をサポートしていますが、1 行のコードしか必要としません。

私の個人的な意見では、デフォルトで複数のインクルードを防止し、複数回インクルードされるように設計されたヘッダーにのみガード マクロを要求する方が良いでしょう(オーバーヘッドは非常に少数のユース ケースに任せてください)。ただし、これは C が最初に実装された方法ではありません (さらに、プリプロセッサがより複雑になります)。したがって、変更される可能性はほとんどありません。

于 2012-04-25T17:32:57.040 に答える
0

まあ、それはCが機能するようなものです...オブジェクトの実際の実装を提供するため、定義です。

于 2012-04-25T17:22:00.087 に答える
0

@Kirilenkoが言ったように、定義はオブジェクトの実装を提供しているため、それらを2回定義することはできません。しかし、あなたの質問も何か他のことを尋ねているのではないかと思います。

編集:インスタンス化を定義に変更します。

s の定義

struct s {
    int a;
    char b;
};

.c ファイルに入れるか、少なくとも構造体を .h ファイルに展開して構造体のインスタンス化を .c ファイルに入れるか、.h ファイルで typedef を使用します。

typedef struct s {
    int a;
    char b;
} my_struct_type;

.h ファイルで定義された構造体が必要な場合でも、そのように括弧で囲むことで、「2 回定義される」ことを防ぐことができます。

編集: マクロ #ifdef MY_STRUCT_DEFINED struct s { int a; からアンダースコアを削除しました。文字 b; }; #endif

于 2012-04-25T17:42:02.963 に答える