1
struct Intx4 {
  int data[4];
};

Intx4 loadIntx4(void const *p) {
  auto up alignas(1) = (int const *)p; // Does this line correct? (compiled ok in clang)
  Intx4 r;
  for (int i = 0; i < 4; i++) r.data[i] = up[i];
  return r;
}

我还尝试了以下方法,它们都无法在 clang 中编译:

int const *up alignas(1) = (int const *)p;
auto up = (int const alignas(1) *)p;
4

3 回答 3

4

要读取未对齐的整数:

int i;
void* ptr_to_unaligned;
...
memcpy (&i, ptr_to_unaligned, sizeof(i));

C++ 中没有未对齐的整数类型,因此您必须使用void*.

于 2015-08-17T13:27:41.343 回答
3

根据 C++11 草案 (n4296),尝试将指向 void 的指针转换为具有对齐要求的类型会调用未定义的行为

从 5.2.9 静态转换第 13 节开始:“指向 cv1 void 的指针”类型的纯右值可以转换为“指向 cv2 T 的指针”类型的纯右值,其中 T 是对象类型,而 cv2 与 cv 限定相同,或大于 cv1... 如果原始指针值表示内存中字节的地址 A 并且A 满足 T 的对齐要求,则生成的指针值表示与原始指针值相同的地址,即是,A。任何其他此类指针转换的结果都是未指定的(强调我的)

我知道您使用的是显式转换(或 C 样式转换),但 5.4 显式转换说:由 const_cast (5.2.11)、static_cast (5.2.9)、static_cast 后跟 const_cast、a reinterpret_cast (5.2.10) 或 reinterpret_cast 后跟 const_cast,可以使用显式类型转换的强制转换表示法执行。相同的语义限制和行为适用......

因此,在您的情况下,显式转换与static_cast<int const *>(p).

当您尝试访问未对齐的 int 指针时,某些架构(尤其是 ARM 架构)会陷入陷阱,如其他 SO 答案中所述

于 2015-08-17T13:29:13.123 回答
1

要以非对齐方式使用整数,请将单词 __packed 放在整数指针声明的前面:

__packed int *pi; // pointer to unaligned int

C 和 C++ 代码中未对齐的指针

于 2018-09-08T12:55:16.760 回答