c - C 结构成员是否继承编译器属性?

标签 c gcc struct memory-alignment

对于大多数 C 编译器,可以在结构上指定编译器属性,这些属性定义该结构的成员在内存中的对齐方式。例如:

typedef struct{
    char a;
    char b;
} __attribute__((aligned(2))) TwoChars;

如果 char a 结束于地址 0xA(为简单起见),那么 char b 将不会位于地址 0xB,而是 0xC,因为它对齐到 2 个字节.

我的问题是:结构成员是否继承了这个属性?例如:

typedef struct{
    char a;
    char b;
} TwoChars;

typedef struct {
    TwoChars tc;
    char c;
} __attribute__((aligned(1))) ThreeChars;

这最终在内存中看起来像什么? } __attribute__((aligned(2))) TwoChars 怎么样?

最佳答案

注意:这是一个非标准的特定于编译器的扩展。我在回答中提到的内容可能适用于 GCC 和 Clang,我认为这就是您所说的“大多数 C 编译器”。


one can specify compiler attributes on a struct that define how the members of that struct are aligned in memory

不,这不是 __attribute__((aligned(...))) 的工作方式。 aligned 属性仅适用于结构本身,不适用于其字段。见亲documentation page .

如果你想控制结构字段的对齐方式,你将不得不使用它们的属性。

这个:

struct {
    char a;
    char b;
} __attribute__((aligned(8))) foo = { 1, 2 };

将编译成类似的东西:

foo:
    .byte   1
    .byte   2
    .zero   6

同时:

struct {
    char a __attribute__((aligned(2)));
    char b __attribute__((aligned(2)));
} bar = { 1, 2 };

会做你想做的事:

bar:
    .byte   1
    .zero   1
    .byte   2
    .zero   1

因此:

is this property inherited by struct members?

没有。对齐不是由结构成员继承的东西。


一件有趣的事情是,packed 属性是否由应用它的结构内的嵌套结构的成员继承,因为 packed 专门用于由结构成员继承。文档没有明确说明是否是这种情况,但我们可以很容易地检查这一点。

以下代码:

struct foo {
    char a;
    int b;
    char c;
};

struct bar {
    struct foo d;
    char e;
    int f;
} __attribute__((packed));

struct bar x = {{101, 102, 103}, 104, 105};

编译为:

x:
    .byte   101
    .zero   3
    .long   102
    .byte   103
    .zero   3
    .byte   104
    .long   105        

从上面我们可以看出,packed只适用于bar的成员,不会被foo的成员继承,而将 __attribute__((packed)) 添加到 foo 会产生以下内容:

x:
    .byte   101
    .long   102
    .byte   103
    .byte   104
    .long   105

如果您想知道,这也适用于在其他结构中定义的结构:

struct bar {
    struct {
        char a;
        int b;
        char c;
    } d;
    char e;
    int c;
} __attribute__((packed));

struct bar x = {{101, 102, 103}, 104, 105};

产生:

x:
    .byte   101
    .zero   3
    .long   102
    .byte   103
    .zero   3
    .byte   104
    .long   105        

而将 __attribute__((packed)) 添加到 d 会产生:

x:
    .byte   101
    .long   102
    .byte   103
    .byte   104
    .long   105

关于c - C 结构成员是否继承编译器属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64653605/

相关文章:

我可以在调用 X509_STORE_add_cert(X509_STORE *ctx, X509 *x) 后释放 X509 *x 吗?

c - 服务器验证凭据(套接字编程)

c - 在 gcc 内联汇编程序 (ARM) 中使用数组

c - GCC -O3 6.1.1、5.3.1、4.1.2 无法编译正确的可执行文件(C 中的递归合并排序)

c# - 比较日期时发生 StackOverflowException

c - 用 C 代码实现哥德巴赫猜想

c - 我的 makefile 有什么问题?

c++ - 哪个版本的 GNU GCC 支持 TR1 外部模板?

c - 创建房间的结构,然后将每个房间写入各自的唯一文件

c - 错误 : invalid type argument of unary '*' (have 'int' )