4

具体的には、次のようなものを作成できるかどうか疑問に思っていました。

typedef struct {
    char *s; /* still a cstr, with '0' bit at end */
    size_t len;
} str;
str *newstr(char *s) {/*...*/};
void freestr(str *s) {/*...*/};

そしてこのようなことをします(stdlib/string関数を持つcstrとして扱います):

int main() {
    str *s = newstr("hello");
    printf("The first character of '%s' is '%c'", *s, (*s)[0]);
    freestr(s);
}

そうでなければ、それは大したことではありません。もちろん、私は1バイトを無駄にすることについてはあまり心配していません。

4

3 に答える 3

12

いいえ、それは標準がパディングの配置を明示的に禁止している場所です。構造体の最初のメンバーのアドレスと構造体のアドレスは同じである必要があります。

C2011標準のn1570ドラフトのセクション6.7.2.1(15)は、次のように述べています。

構造体オブジェクト内で、非ビットフィールドメンバーとビットフィールドが存在するユニットには、宣言された順序で増加するアドレスがあります。適切に変換された構造体オブジェクトへのポインタは、その最初のメンバー(または、そのメンバーがビットフィールドの場合は、それが存在するユニット)を指し、その逆も同様です。構造体オブジェクト内に名前のないパディングがある場合がありますが、最初はありません。

(強調鉱山)

于 2012-11-03T14:53:26.653 に答える
7

いいえ。C 標準では、構造体の最初の要素の前にパディングがないことを要求しています。しかし、それはそれが保証する唯一のものです。さらにフィールド間に (文書化されていないサイズの) パディングがある場合があります。

ISO C99 標準から: (6.7.2.13):

13 構造体オブジェクト内で、非ビットフィールドメンバーとビットフィールドが存在するユニットは、宣言された順序で増加するアドレスを持ちます。適切に変換された構造体オブジェクトへのポインターは、その最初のメンバー (または、そのメンバーがビットフィールドの場合は、それが存在するユニット) を指し、その逆も同様です。構造体オブジェクト内に名前のないパディングがある場合がありますが、先頭にはありません。

于 2012-11-03T14:53:47.883 に答える
5

いいえ。

(C99、6.7.2.1p13) 「構造体オブジェクト内に名前のないパディングがある場合がありますが、先頭にはありません。」

任意の構造体メンバー (最後のものを含む) の後にパディングがある場合がありますが、最初の構造体メンバーの前にパディングがあってはなりません。

于 2012-11-03T14:54:49.627 に答える