c - 有关于 C 结构顺序的任何保证吗?

标签 c pointers struct

我广泛使用了结构体,也看到了一些有趣的东西,尤其是 *value而不是 value->first_value其中 value 是指向结构的指针,first_value是第一个成员,是*value安全的?

另请注意,由于对齐,无法保证大小,基于架构/寄存器大小的 alginment 值是什么?

我们对齐数据/代码以加快执行速度我们可以告诉编译器不要这样做吗?所以也许我们可以保证关于结构的某些事情,比如它们的大小?

在对结构成员进行指针运算以定位成员偏移量时,我认为您这样做 -如果小端+对于大端,还是仅取决于编译器?

malloc(0) 真正分配了什么?

以下代码用于教育/发现目的,并不意味着具有生产质量。

#include <stdlib.h>
#include <stdio.h>

int main()
{
    printf("sizeof(struct {}) == %lu;\n", sizeof(struct {}));
    printf("sizeof(struct {int a}) == %lu;\n", sizeof(struct {int a;}));
    printf("sizeof(struct {int a; double b;}) == %lu;\n", sizeof(struct {int a; double b;}));
    printf("sizeof(struct {char c; double a; double b;}) == %lu;\n", sizeof(struct {char c; double a; double b;}));

    printf("malloc(0)) returns %p\n", malloc(0));
    printf("malloc(sizeof(struct {})) returns %p\n", malloc(sizeof(struct {})));

    struct {int a; double b;} *test = malloc(sizeof(struct {int a; double b;}));
    test->a = 10;
    test->b = 12.2;
    printf("test->a == %i, *test == %i \n", test->a, *(int *)test);
    printf("test->b == %f, offset of b is %i, *(test - offset_of_b) == %f\n",
        test->b, (int)((void *)test - (void *)&test->b),
        *(double *)((void *)test - ((void *)test - (void *)&test->b))); // find the offset of b, add it to the base,$

    free(test);
    return 0;
}

调用 gcc test.c其次是 ./a.out我明白了:
sizeof(struct {}) == 0;
sizeof(struct {int a}) == 4;
sizeof(struct {int a; double b;}) == 16;
sizeof(struct {char c; double a; double b;}) == 24;
malloc(0)) returns 0x100100080
malloc(sizeof(struct {})) returns 0x100100090
test->a == 10, *test == 10 
test->b == 12.200000, offset of b is -8, *(test - offset_of_b) == 12.200000

更新
这是我的机器:
gcc --version
i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
uname -a
Darwin MacBookPro 10.8.0 Darwin Kernel Version 10.8.0: Tue Jun  7 16:33:36 PDT 2011; root:xnu-1504.15.3~1/RELEASE_I386 i386

最佳答案

从 6.2.5/20 开始:

A structure type describes a sequentially allocated nonempty set of member objects (and, in certain circumstances, an incomplete array), each of which has an optionally specified name and possibly distinct type.



回答:

especially *value instead of value->first_value where value is a pointer to struct, first_value is the very first member, is *value safe?



见 6.7.2.1/15:

15 Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.1



然而,结构末尾可能有填充字节,也可能在成员之间。

在 C 中,malloc( 0 )是实现定义的。 (作为旁注,这是 C 和 C++ 不同之处之一。)

[1] 强调我的。

关于c - 有关于 C 结构顺序的任何保证吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11057174/

相关文章:

c - 多线程应用程序中的错误处理

c - 在指针中填充 -1 作为特殊值

c - 将指针与数组一起使用时遇到问题

go - 包的类型不能用作 vendored 包的类型

c - 为什么我不能列出存储在数组中的字符串?

c++ - 一个类似 DSL 的小型 lisp,可以编译成 C/C++ 代码——Antlr 是一个不错的选择吗?

c++ - 在 C++、结构或类中应该使用什么来创建链接列表

c - 取消引用结构指针内的指针

c - 将大量线程固定到单个 CPU 会导致所有内核的利用率激增

c - 从结构修改字符串数组