2

Cの構造体にフィールドを追加したいので、たとえば、次の構造があります。

struct A
{
 some_type x;
 some_type y;
}

このように、新しい構造体を宣言します。

struct B
{
 A a;
 some_type z;
}

今、私はこのような機能を持っているとしましょう。

int some_function( A * a )

プログラムでこのようにタイプ B の変数を渡すことは可能ですか。

B * b;
......
A * a = (A*)b;
some_function( a );

また、たとえばsome_function使用して内部のフィールドを使用することもできますか?a->x

4

5 に答える 5

9

Yes, it is valid. Word of the Standard, C99 6.7.2.1/13:

... A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.

于 2012-06-03T16:55:38.430 に答える
1

はい、うまくいきます。A a は構造体の最初のメンバーになります

これは、一部の人々がCでオブジェクト指向継承をシミュレートした方法です

あなたは使用することができます

  &b->a

キャストの代わりに。そして、おそらく ASSERT のようにします

 ASSERT (&b->a == b)

このセマンティックを誤って破棄した場合に警告される

于 2012-06-03T16:49:58.043 に答える
1

メンバーのメソッドを呼び出さないのはなぜですか?

some_function( &b->a );

コードは動作するようになりましたが、誰かが のメンバーを変更することを決定した場合はどうなりBますか? または、前に新しいメンバーを追加しaますか?

于 2012-06-03T16:52:40.333 に答える
0

はい、これは機能しますが、偶然にすぎません。

私がC99標準を正しく思い出せば、この特定のケースは、期待どおりに機能するために特に必要です。しかし、これは、十分に多くの人々がそれ以前にそれが機能することに依存していたためであり、十分に多くの実装で偶然に機能したため、C99標準委員会は事実上だけでなく正当に機能することを法制化する義務があると感じたことは明らかです。

これが良い考えだと思わせないでください。

標準のエッジケースに依存するものはすべて、ハッキーに見え(したがって、コードの将来の読者を不快にさせます)、賢く見えます(これにより、何かを変更/修正することに神経質になります)。また、それは人々を仮定に導きます。あなたはすでに正当なものの端にいるので、国境を越えて人々を壊れたコードに誘惑する可能性があります。たとえば、構造体内の最初のサブ構造内の最初の要素が期待どおりに整列されているという事実は、他のサブ要素が整列していることを意味するものではありません。それがあなたのコンパイラで機能するという事実は、それが他の誰かのために機能することを意味するものではなく、気が遠くなるほど混乱するバグにつながります。

書く:

A *a = &(b->a);

(上記のコメントが示唆しているように)そしてあなたの意味は明らかです。

なんらかの理由でキャストB*する必要がある場合は、必要なことを実行する以外に選択肢がない理由を説明する非常にA*明確なコメントを書き、読者にそれが合法であることを保証し、C99標準のサブサブセクションを指し示します。ライセンスを取得します。

あなたが本当にそのサブセクションを見つけることができない(そしてそれがあなたの宿題/罰であると見つける)なら、このようにコメントしてください、そして私はそれを掘り下げます。

于 2012-06-03T17:14:36.160 に答える
0

いいえ、うまくいきません。少し変更するとうまくいきます

struct A
{
 some_type x;
 some_type y;
}; /* <- note semicolon here */


struct B
{
 struct A a;
 some_type z;
}; /* ... and here */


int some_function(struct A *a ); /* ... and here ... */


struct B *b;
......
struct A *a = (struct A*)b;
some_function( a );
于 2012-06-03T16:59:24.263 に答える