次のような小さなデータ非表示モジュールがあります。
/** mydata.h */
struct _mystruct_t;
typedef struct _mystruct_t mystruct;
mystruct *newMystruct();
void freeMystruct( mystruct** p );
/** mydata.c */
#include "mydata.h"
struct _mystruct_t {
int64_t data1;
int16_t data2;
int16_t data3;
};
// ... related definitions ... //
ほとんどの場合、これが私が望んでいることです。シンプルですが、構造体には厳密な一貫性要件があり、データ メンバーへのアクセスを提供したくありません。
問題は、クライアント コードで、スタックに割り当てたい別の構造体に構造体を含めたいことです。mystruct*
現在、いくつかのクライアント コードで sを解放するためにフープをジャンプしています。a) mystruct はかなり小さいので、すぐに大きくなるとは思いません。b) mystruct を変更した場合にクライアント コードを再コンパイルしなければならないことは問題ではないので、mystruct のサイズを公開したいと思います。 (つまり、ヘッダー内)。
私が検討した2つの可能性:
/** mydata.h */
typedef struct {
// SERIOUSLY DON'T ACCESS THESE MEMBERS
int64_t data1;
int16_t data2;
int16_t data3;
} mystruct;
ここでの欠点がそれ自体を物語っていると思います。
また
/** mydata.h */
#define SIZEOF_MYSTRUCT (sizeof(int64_t)+sizeof(int16_t)+sizeof(int16_t))
// everything else same as before...
/** mydata.c */
// same as before...
_Static_assert (SIZEOF_MYSTRUCT == sizeof(mystruct), "SIZEOF_MYSTRUCT is incorrect")
もちろん、この値を手動で更新する必要があるため、これは理想的ではないように思われます。また、構造体のアライメントが実際にこれを不正確にする可能性があるかどうか、またはその方法がわからないためです (この質問を書いているときに静的アサートについて考えましたが、部分的に対処していますこの懸念)。
これらのいずれかが優先されますか? または、さらに良いことに、ヘッダーに実際の構造体定義を提供し、後でメンバーにアクセスする機能を何らかの形で隠すための巧妙なトリックはありますか?