【问题标题】:Alignment of compound type objects in C90 and C99C90 和 C99 中复合类型对象的对齐方式
【发布时间】:2016-09-05 18:17:16
【问题描述】:

请考虑以下类型:

typedef struct { char myArray[300]; } MyStruct;
typedef union  { char myArray[300]; } MyUnion;

typedef struct { uint64_t x; } MyStruct2;
typedef union  { uint64_t x; } MyUnion2;

typedef struct { uint64_t x; char myArray[300]; } MyStruct3;
typedef union { uint64_t x; char myArray[300]; } MyUnion3;

我可以找到有关复合类型成员的对齐和填充的信息,但我不确定这些类型本身的对象。

哪些对齐规则适用于在 X86 平台上使用 C90 和 C99 的 RAM 中这些类型的对象?对齐方式可以改变吗?因为优化器删除了未使用的成员(尤其是在联合中)?

【问题讨论】:

  • 对象的对齐方式是实现定义的。如果要设置特定值,则应使用编译器特定属性或 _Alignas。
  • _Alignas 是可移植的,但不是 C99。
  • “C 和 C99”是什么意思?您是指“C11 和 C99”还是“C90 和 C99”或其他标准组合(或准标准 C)?但是对齐是实现定义的。
  • 不允许编译器从联合体或结构体中删除未使用的成员。
  • 编译器无法合理地确定成员未被使用,因此不会从联合或结构中删除“未使用”成员(实际上,联合是另一回事,因为“未使用”是什么意思?)。跨度>

标签: c struct c99 unions memory-alignment


【解决方案1】:

对象的对齐是实现定义的。如果要设置特定值,则应使用编译器特定属性。

编译器无法合理地确定成员未使用,因此不会从联合或结构中删除“未使用”成员(实际上,联合是另一回事,因为“未使用”是什么意思?)。

编译器可以确定的唯一情况是在结构的编译单元中仅创建静态或自动变量,这些变量永远不会传递给编译单元之外的函数和一个或多个成员从不在语句中使用。可能我忘记了一些与这种推理不相符的东西。

我认为在所有其他情况下,编译器无法确定没有使用成员。例如,如果将它传递给另一个编译单元中的函数,则编译器无法更改定义,因为其他函数将依赖于定义并且可能正在使用此编译单元中未使用的成员。

对于联合,编译器永远无法确定,因为成员的内存是共享的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多