gpt4 book ai didi

c++ - 对齐/偏移结构的特定成员

转载 作者:行者123 更新时间:2023-11-30 04:45:07 27 4
gpt4 key购买 nike

在结构内对齐成员的最佳或常规方法是什么?添加虚拟数组是最佳解决方案吗?

我有一个 double 的结构和 double 的三倍是吗?

struct particle{
double mass;
std::tuple<double, double, double> position;
}

如果我有这些的数组,内存将是这样的

[d][d  d  d][d][d  d  d][d][d  d  d]...

问题是第一个三元组到第二个三元组的距离不是sizeof(std::tuple<double, double,double>)==3*sizeof(double)的整数倍,因此我无法将交错的三元组数组解释为具有步幅的数组。

换句话说,给定一个粒子数组 particle ps[100] , 我可以将成员的地址取到第一个元素 triple* v1P = &(ps[0].position)我想要那个v1P + n == &(ps[1].position)对于一些(整数)n (我可以在编译时推断出,例如 n = sizeof(particle)/sizeof(tripe) if sizeof(particle)%sizeof(tripe)==0 。)

强制三元组具有不同偏移量的最佳方法是什么?

我可以人工贴一些double s 在中间以匹配偏移量:

struct particle{
double mass;
double garbage[2];
std::tuple<double, double, double> position;
}

所以内存看起来像这样

[d][*  *][d  d  d][d][*  *][d  d  d][d][*  *][d  d  d]...

但是我不能使用初始值设定项 ( particle{1.,{1.,2.,3.}} )。

我也可以把它加到最后

struct particle{
double mass;
std::tuple<double, double, double> position;
double garbage[2];
}

所以,我可以继续使用初始化程序。这是最好的方法吗?但它只适用于这种简单的情况。

另一种选择是强制对齐 struct3*sizeof(double) 的一些倍数

struct alignas(3*sizeof(double)) particle{double mass; std::tuple<...> position;};

但问题是它不是 2 的幂,所以 GCC 和 clang 拒绝它。请注意,在其他大小的元组中 alignas策略之所以有效,是因为它可以解决不小心成为 2 的幂的问题。

例如在

struct alignas(4*sizeof(double)) particle{double mass; std::pair<double, double> position;};

alignas为这个其他用例(在 GCC 中)提供了一个简单的解决方案。

对此是否有通用或公认的解决方案?

我还发现了 ((packed)) , 在这个解决方案中是否也有必要?


我找到了这篇旧文章https://www.embedded.com/design/prototyping-and-development/4008281/2/Padding-and-rearranging-structure-members , https://web.archive.org/web/20190101225513/http://www.drdobbs.com/cpp/padding-and-rearranging-structure-member/240007649 .似乎在中间添加数组至少在当时是一种解决方案。此外,我可以使用 char[N]以这种方式进行更精细的控制,达到字节级别。

最佳答案

在结构中间添加数组是为结构成员创建正确填充的传统方法,并且没有问题。我有一个 thread关于使用 ((packed))((aligned))如果您想按自己的喜好调整结构。

我可能是错的,但我认为您想要实现的是某种未定义的行为,原因有两个。如果你想按照你描述的方式访问数组中的结构成员:

  1. 您在数组的不同不相关数据成员之间创建关系。
  2. 您不能再直接使用数组的属性。例如,你如何理解你是数组的最后一个成员?您需要将成员的地址与数组的结束地址进行比较。

虽然,如果您将结构填充设置为 1(使用 ((packed)))应该可以保证您想要执行的操作,但我个人并不建议这样做。

更新以下结构:

struct particle{
double mass;
__attribute__((aligned(2*sizeof(double)))) std::tuple<double, double, double> position;
};

给你类似的步伐:

struct particle{
double mass;
double garbage[2];
std::tuple<double, double, double> position;
}

但是自tuple<>是非 POD,您不能使用 ((packed))属性。刚刚收到这个警告,我自己正在尝试对其进行测试。

关于c++ - 对齐/偏移结构的特定成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57424150/

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