繁体   English   中英

POD结构(相同类型的成员):是连续内存位置的成员吗?

[英]POD struct (members of same type): are members in contiguous memory locations?

特定

template <typename T>
struct Vector3d { T x, y, z; };
  • 假设x,y和z位于连续的内存位置是否安全?

  • 假设T = floatT = double ,至少可以安全吗?

  • 如果不是可以跨平台方式实施?

注意:只要x,y,z是有条件的,我不介意在z之后填充

假设x,y和z位于连续的内存位置是否安全?

从技术上讲,语言没有这种保证。

另一方面,他们也没有必要不连续,他们很可能在实践中是连续的。

如果不是可以跨平台方式实施?

使对象保证位于连续内存位置的跨平台方式是一个数组:

template <typename T>
struct Vector3d { T components[3]; };

数组也使得使用指针算法迭代对象是合法的。

假设xyz位于连续的内存位置是否安全?

该标准没有做出这样的保证。

但实际上,一个理智的实现不会在相同类型的相邻字段之间插入任何填充(因为这种填充永远不是必需的1 )。

如果您想要额外的安全性,请添加static_assert

static_assert(sizeof(Vector3d<float>) == 3 * sizeof(float));

假设T = floatT = double ,至少可以安全吗?

据我所知,字段类型在这里没有任何区别。


1 - 保证数组不包含填充。 由于您可以创建任何类型的数组,因此实现必须能够在没有填充的情况下将任何单个类型的对象彼此相邻地存储。

不存在绝对不保证相同类型的结构元素之间没有填充,即使对于“大”普通旧数据类型(例如double 此外,未指定在指向另一个元素的指针上通过指针算法到达元素的行为。

写得好多了

template <typename T>
struct Vector3d { T t[3]; };

保证连续性和指针算术,并为xyz提供访问函数。

如果你不喜欢调用函数的语法,并且愿意容忍一些最有可能在struct本身中出现的开销,那么你总是可以绑定引用:

template <typename T>
struct Vector3d
{
    T t[3];
    T& x = t[0];
    T& y = t[1];
    T& z = t[2];
};

填充被添加到结构和类的唯一原因是满足其成员的对齐要求。 注意,结构的对齐是其成员与最大对齐要求的对齐。 结构的大小是其对齐的倍数,添加尾随填充以满足该要求。

由于Vector3d的成员属于相同类型,因此已经满足对齐要求,因此,在成员之间或结构的末尾没有任何填充。

C ++标准中没有要求无缘无故地插入任意填充。

要100%确定,请输入static_assert

static_assert(sizeof(Vector3d<float>) == 3 * sizeof(float), "Unexpected layout.");
static_assert(sizeof(Vector3d<double>) == 3 * sizeof(double), "Unexpected layout.");

有些人说C ++标准中没有明确规定保证,因此,人们不能依赖它。 但是,C ++标准通常不够明确,因此需要了解其背后的基本原理。 在我个人看来,这些人没有充分的理由传播恐惧,不确定和怀疑。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM