【问题标题】:Can a C compiler add padding before the first element in a structure?C 编译器可以在结构中的第一个元素之前添加填充吗?
【发布时间】:2012-11-03 14:51:52
【问题描述】:

具体来说,我想知道我是否可以制作这样的东西:

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

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

【问题讨论】:

  • 当然你不能像那样订阅你的结构 - 你需要 C++ 来做运算符重载。
  • printf() 调用不起作用 - 它需要一个 char* 和一个 char,但您实际上传递了一个 char** 和一个 char*
  • 你的意思是:printf("The first character of '%s' is '%c'", *s, (*s)[0]);,不是吗?
  • @alk: 哦哦,谢谢你的收获。

标签: c


【解决方案1】:

不,这是标准明确禁止放置任何填充的地方。 struct的第一个成员的地址和struct的地址必须相同。

C2011 标准的 n1570 草案中的第 6.7.2.1 (15) 节规定:

在结构对象中,非位域成员和位域所在的单元的地址按声明顺序递增。 一个指向结构对象的指针,经过适当转换,指向它的初始成员(或者如果该成员是位域,则指向它所在的单元),反之亦然。 可能有结构对象内的未命名填充,但不在其开头。

(强调我的)

【讨论】:

    【解决方案2】:

    没有。 C 标准要求结构中的第一个元素之前没有填充。但这是它唯一能保证的。其他字段之间可能存在(未记录大小的)填充。

    来自ISO C99 Standard:(6.7.2.13):

    13 在结构对象中,非位域成员和位域所在的单元 驻留的地址按照它们被声明的顺序增加。一个指针 适当转换的结构对象指向其初始成员(或者如果该成员是 位域,然后到它所在的单元),反之亦然。可能有无名 在结构对象内填充,但不在其开头。

    【讨论】:

      【解决方案3】:

      没有。

      (C99, 6.7.2.1p13) "结构中可能存在未命名的填充 对象,但不是在其开头。”

      在任何结构成员(包括最后一个)之后可以有填充,但在第一个结构成员之前不能有填充。

      【讨论】:

        猜你喜欢
        • 2010-10-29
        • 2020-11-27
        • 2010-11-07
        • 2011-12-12
        • 2021-05-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-22
        相关资源
        最近更新 更多