1

構造体の特定のメンバーのサイズを取得したい。

sizeof(((SomeStruct *) 0)->some_member)私にとってはうまくいきますが、もっと良い方法があるのではないかと思います。

#define SIZEOF_ELEM(STRUCT, ELEM) sizeof(((STRUCT *) 0)->ELEM)使用することもできSIZEOF_ELEM(SomeStruct, some_member)ましたが、もっと良いものがすでに組み込まれているのではないかと思います。

私の特定のユースケースはhsc2hs(Haskell Cバインディング)です。

pokeArray (plusPtr context (#offset AVFormatContext, filename)) .
  take (#size ((AVFormatContext *) 0)->filename) .
  (++ repeat '\NUL') $ filename
4

4 に答える 4

5

あなたが持っているのは、逆参照する変数があることを保証できない場合と同じくらいきれいです。(可能であれば、もちろん、sizeof(var.member)またはを使用しますsizeof(ptr->member)が、コンパイル時定数が必要な一部のコンテキストではこれは機能しません。)

昔々(1990年頃)、offsetofベースアドレス0を使用して定義されたコンパイラに遭遇し、クラッシュしました。私はハッキング<stddef.h>して0ではなく1024を使用することで問題を回避しました。しかし、今はそのような問題に遭遇するべきではありません。

于 2009-06-18T19:51:44.080 に答える
3

私はあなたがすでにそこに正しい解決策を持っていると信じています。stddef.hを掘り下げて、offsetofがどのように定義されているかを調べることができます。これは、非常によく似た処理を行うためです。

パディングにより、メンバーのサイズと、そのメンバーと次のメンバーのoffsetofsとの間に違いがある可能性があることに注意してください。

于 2009-06-18T19:52:37.103 に答える
3

C ++ではsizeof(SomeStruct :: some_member)を実行できますが、これはcであり、スコープ解決演算子はありません。私の知る限り、あなたが書いたものは、書くことができる限り良いものです。

于 2009-06-18T19:53:08.507 に答える
3

Microsoft には、ヘッダーの 1 つに次のものがあります。

#define RTL_FIELD_SIZE(type, field) (sizeof(((type *)0)->field))

別のことをする理由はありません。

関連するマクロがあります:

RTL_SIZEOF_THROUGH_FIELD()
RTL_CONTAINS_FIELD()

そして気の利いた:

CONTAINING_RECORD() 

これにより、リンク フィールドが構造体の先頭にある必要がなく、ストレート C でジェネリック リストを実装できます。詳細については、このKernel Mustard の記事を参照してください。

于 2009-06-18T20:03:38.033 に答える