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);
}

如果不是,这没什么大不了的——当然,我并不真正担心浪费一个字节。

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 回答