gpt4 book ai didi

c - 我怎样才能让 gcc 像数组访问一样对待开关中的字段访问?

转载 作者:太空宇宙 更新时间:2023-11-04 01:05:17 25 4
gpt4 key购买 nike

例如,-O3 处的 GCC 4.9.0 编译此

typedef struct {
double x, y, z;
} vector;

double
vector_get(const vector *v, size_t i)
{
switch (i) {
case 0:
return v->x;
case 1:
return v->y;
case 2:
return v->z;

default:
__builtin_unreachable();
}
}

比较和跳转(更大的例子得到一个跳转表)。但最佳编译只是

return ((double *)v)[i];

(如果已定义)。显而易见的解决方案是将单独的vector字段替换为数组,但是编写.x.y等的能力大大提高代码其他部分的可读性。

最佳答案

您的问题是关于 gcc 的,但您似乎希望尽可能与标准 C 兼容。

标准 C 给出了一些关于给定结构变量中结构成员的对齐属性的知识。这允许执行一些操作,比如计算结构中成员之间的偏移量。您需要知道此偏移量才能以“指针模式”执行对“结构变量”的访问。

但是,您似乎想要恰恰相反:访问“指针或数组”就好像它是“结构”一样。这不能保证有效,因为结构可能在两个连续元素之间有填充字节。但是在数组中,保证所有连续的元素都在内存中,没有任何填充。

我的结论是,一般来说,您尝试做的事情会让您出错。
这在语法上并非不可能,但问题是字节的对齐取决于编译器:它无法预测。

我们可以肯定地说:

  • doubles 的 3 个元素组成的数组具体来说,在 double 类型的 3 个连续对象中的存储空间(内存)中保存一个连续字节 block 。 .
  • 三个元素的结构 x,y,z double 类型按照成员声明的顺序保存在一个连续字节 block 中。所以.x < .y < .z .
  • 结构的字节可以用memcpy()复制因此,特别是可以访问这些字节的相对地址(从结构的第一个字节的地址开始)。
  • 它可能是连续元素之间的填充字节。所以,.y的地址不一定是成员(member)的地址 .x “加号”sizeof(double) .
  • 结构的第一个成员的地址与结构本身的地址一致。这意味着开头没有填充字节。
  • 结构的末尾可能有填充字节。

填充字节的选择取决于编译器。

因此,不能保证使用并集进行类型双关可以为您提供预期的可移植结果。

关于c - 我怎样才能让 gcc 像数组访问一样对待开关中的字段访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24844455/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com