c - 分配兼容的聚合类型时,字段分配的顺序是什么
问题描述
我整个晚上都在寻找标准的,没有运气。也许我错过了一些东西!
在下面的代码示例中,在分配过程中,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 2018 6.5.16.1 只说:
2 在简单赋值(
=
) 中,右操作数的值被转换为赋值表达式的类型,并替换存储在左操作数指定的对象中的值。3 如果存储在一个对象中的值是从另一个对象中读取的,该对象以任何方式与第一个对象的存储重叠,则重叠应准确,并且两个对象应具有兼容类型的合格或不合格版本;否则,行为未定义。
检查所有提及“成员”、“结构”或“结构”的标准并没有发现任何会对作业中的成员施加任何时间顺序的内容。(甚至没有明确定义结构的值是什么;我们只能假设它实际上是其成员值的有序元组,或者也许,从“结构是由一系列成员”在 6.7.2.1 6 中,它的值是其成员的值序列。)
推荐阅读
- ssl - 用于代理间通信的 Kafka SSL 身份验证问题
- php - WordPress:如何防止使用functions.php显示子类别的帖子?
- c++ - 将小数转换为平衡的七文体
- r - 根据选定的标签面板显示侧边栏内容
- javascript - 单击 Material UI 更改波纹颜色
- javascript - 如何在媒体查询中禁用鼠标移动悬停
- python - Django过滤器基于perform_create中的请求数据
- c# - 如何在asp.net web api中制作小密码重置令牌?
- ios - iOS 仅在 NavigationController 根目录上显示标签栏
- c# - 使用 sql 中的列在登录页面中设置角色