首页 > 解决方案 > 分配兼容的聚合类型时,字段分配的顺序是什么

问题描述

我整个晚上都在寻找标准的,没有运气。也许我错过了一些东西!

在下面的代码示例中,在分配过程中,copy into 是与 copy intouint32_t a顺序排列的,还是定义了这个实现?uint32_t b*one = *two

typedef struct __attribute__((packed)) {
  uint32_t a;
  uint32_t b;
} x_t;

extern x_t volatile* get_volatile_x();
extern x_t const* get_const_x();

void foo()
{
  x_t volatile* one = get_volatile_x();
  x_t const* two = get_const_x();

  *one = *two;
}

神螺栓: https ://godbolt.org/z/Vl0fdM

这是一个示例,其中使用某些 ARM 标志,加载按 [a, b] 顺序完成,但存储按 [b, a] 顺序完成。

#include <stddef.h>
#include <stdint.h>

typedef struct __attribute__((packed)) {
  volatile uint32_t a;
  volatile uint32_t b;
} x_t;

extern x_t* get_x();
extern x_t volatile* get_volatile_x();
extern x_t const* get_const_x();

void foo()
{
  x_t* one = get_x();
  x_t const* two = get_const_x();

  *one = *two;
}

神螺栓: https ://godbolt.org/z/FcRbhm

作为一个有趣的事实(我对上面的 C 问题比对这个细节更感兴趣)这个代码不会用 C++ 编译器编译。你会得到一个类似的错误:

<source>:4:9: note: candidate function (the implicit move assignment operator) not viable: 'this' argument has type 'volatile x_t', but method is not marked volatile

因为它看起来像 C++ 期待一个operator=()将它作为一个volatile. 类似于:https ://godbolt.org/z/lt30dJ ,尽管这在 C++ 中也不是很正确。

标签: c

解决方案


在分配结构时,C 标准没有定义结构内成员分配的顺序。

关于作业,C 2018 6.5.16.1 只说:

2 在简单赋值( =) 中,右操作数的值被转换为赋值表达式的类型,并替换存储在左操作数指定的对象中的值。

3 如果存储在一个对象中的值是从另一个对象中读取的,该对象以任何方式与第一个对象的存储重叠,则重叠应准确,并且两个对象应具有兼容类型的合格或不合格版本;否则,行为未定义。

检查所有提及“成员”、“结构”或“结构”的标准并没有发现任何会对作业中的成员施加任何时间顺序的内容。(甚至没有明确定义结构的值是什么;我们只能假设它实际上是其成员值的有序元组,或者也许,从“结构是由一系列成员”在 6.7.2.1 6 中,它的值是其成员的值序列。)


推荐阅读