そのため、C99 は、一般的に使用される「柔軟な配列メンバー」ハックをstruct
祝福して、サイズ要件に合わせて過剰に割り当てられる s を作成できるようにしました。これを行うことはほとんどの正常な実装で完全に安全だと思いますが、特定の状況で a の一部のメンバーが必要ないことがわかっている場合、C で「過小割り当て」することは合法struct
ですか?
抽象的な例
タイプがあるとします:
struct a {
bool data_is_x;
void * data;
size_t pos;
};
の場合data_is_x
、 の型はメンバーdata
を使用する必要がある型です。pos
それ以外の場合、これを操作する関数は、のこの特定のコピーのメンバーをstruct
必要としません。本質的に、 はメンバーを持っているかどうかに関する情報を保持し、この情報はの有効期間内に変更されません (悪意のあるいたずら以外では、とにかくほとんどすべてが壊れます)。言うのは安全ですか:pos
struct
struct
pos
struct
struct a *a = malloc(data_is_x ? sizeof(struct a) : offsetof(struct a, pos));
pos
メンバーが必要な場合にのみメンバーにスペースを割り当てるのはどれですか? struct
それとも、問題のメンバーを使用したことがない場合でも、ポインタに対して小さすぎるキャスト空間を使用するという制約に違反していますか?
具体例
私の実際のユースケースは少し複雑です。主にここにあるのは、なぜ私がこれをやりたいのかを理解できるようにするためです。
typedef struct {
size_t size;
void * data;
size_t pos;
} mylist;
for のコードはmylist_create
、 forが項目長 (項目が何であれ) である連続したデータの配列であるがsize > 0
、 forは項目を含む双方向リンク リストの現在のノードであることを指定します。sで動作するすべての関数は、. 存在する場合、データをリンクされたリストとして処理し、「現在の」インデックスがノードを指すようにします。そうでない場合は、「現在の」インデックスが に格納された配列としてデータを処理します。data
size
size == 0
mylist
size == 0
data
pos
メンバーがsize == 0
本当に必要ない場合ですが、必要な場合は. だから私の質問は、これを行うことは合法ですか:pos
size > 0
mylist *list = malloc(size ? sizeof(mylist) : offsetof(mylist, pos));
(未定義の動作のペナルティで) ながら、メンバーにアクセスしようとしない (またはアクセスする必要がない) ことを保証する場合は? それとも、これを行うことを考えるのはUBであると標準のどこかに書かれていますか?size == 0
pos