【问题标题】:What does the standard say about unaligned memory access?该标准对未对齐的内存访问有何规定?
【发布时间】:2018-12-10 02:18:39
【问题描述】:

我搜索了有关非对齐访问的标准,但没有找到任何东西(可能是我不小心)。

这是未定义的行为吗?是否定义了实现?

由于许多当前的 CPU 支持未对齐访问,因此未对齐内存访问由实现定义是明智的。是这样吗?

通过非对齐访问,我的意思是例如:

alignas(int) char buffer[sizeof(int)+1];
int &x = *new(buffer+1) int;
x = 42;

【问题讨论】:

  • 我认为相关部分是 [basic.align]。实现定义。
  • @RaymondChen:我发现的只是对齐值是实现定义的。但没有关于未对齐的访问。你在那儿看到别的东西了吗?
  • 我们怎么知道这是一个未对齐的访问? sizeof(int) 和所需的对齐方式都是实现定义的。可能与char 相同。

标签: c++ language-lawyer c++17 memory-alignment


【解决方案1】:

不,是UB。您不能在未对齐的内存中开始对象的生命周期。来自[basic.life]p1

T 类型对象的生命周期开始于:

  • 获得与类型 T 正确对齐和大小的存储,并且

  • 如果对象有非空初始化,则其初始化完成,

[...]

因此,在您的示例中,x 引用的对象的生命周期甚至还没有开始,因此除了[basic.life]p6 中提到的对象之外的任何其他用法都是 UB。

但是你的实现被允许做的是说未对齐的内存(由使用的底层架构指定)实际上是对齐的,从而使你的代码在 C++ 抽象机器下有效。但是我不确定是否有任何编译器会这样做。

【讨论】:

  • @MaximEgorushkin:这是真的,但这有关系吗?假设要求是4。我的例子的行为实现是定义的,还是UB?阅读引用部分,我认为 Rakete1111 是对的,而且确实是 UB,因为 new int 是在未对齐的指针上调用的。
  • @MaximEgorushkin 无论编译器开发人员决定它应该返回什么。它可以返回1,或者它可以(如在我的GCC上)返回4。如果硬件允许不对齐的访问并带来性能开销,则实现仍然可以返回 4 以使(大多数)整数对齐,从而提高性能。
  • @MaximEgorushkin 可能是alignof 返回的对齐方式。
  • @geza 这是明确的。抽象机器不关心底层硬件的对齐。如果编译器说内存未对齐,那么无论硬件如何,您都会得到 UB。
  • @geza 我理解为“正确”,这是 alignof 返回的。可以改进,我同意。
猜你喜欢
  • 2010-11-07
  • 2013-10-21
  • 2013-05-09
  • 2014-06-25
  • 1970-01-01
  • 1970-01-01
  • 2011-07-04
  • 2012-08-03
相关资源
最近更新 更多