__unaligned说明符何时与指针一起使用?

When is the __unaligned specifier used with pointers?

本文关键字:一起 unaligned 说明符 何时 指针      更新时间:2023-10-16

>Background

我目前正在使用可变长度数组,它们的长度存储在元素的前两个字节中。由于数组未填充,因此单个元素可能未对齐。只有第一个元素保证对齐,整个元素以双 null 结尾。这些数组由我需要访问且无法更改的 API 使用。

我正在编写一个const_iterator,它采用对齐的指针,可以迭代未对齐的元素。这些数组的 API 为指向元素的指针指定了"__unaligned",所以我主要是试图确认或否认我对应用__unaligned说明符的理解。

问题

简单地说:在处理指向潜在未对齐数据的指针时,何时应使用__unaligned说明符?

让我们说我有

Foo *foo = pointerToFirstElement(); //aligned
auto next_ptr = reinterpret_cast<unsigned char *>(foo);
next_ptr += bytesToNextElement(foo);
//reinterpret_cast here to retrieve the next element

然后我是否需要检查新地址是否对齐,如果没有,reinterpret_cast<Foo __unaligned *>(next_ptr)访问下一个元素?

此外,我可以像这样使用__unaligned作为模板参数推导的一部分吗const

template <class T, class = std::enable_if<std::is_pointer<T>::value>>
struct is_pointer_to_aligned_data : std::true_type {};
template <class T>
struct is_pointer_to_aligned_data<T __unaligned *> : std::false_type {};

简单地说:在处理指向潜在未对齐数据的指针时,何时应使用 __unaligned 说明符?

  • 简而言之,当您使用的平台需要它时,例如x86-64上的Windows API。这是对 Itanium 的遗留回归,而不是 x86-32 上的问题。其他一些处理器也存在未对齐数据的问题(例如 MIPS(。

  • 具体来说,__unaligned说明符只是意味着数据可能不在对齐的边界上。它在指针类型之外没有任何意义。

  • 在 32 位 x86 平台上,Windows 本身只是声明#define __unaligned.

然后我是否需要检查新地址是否对齐,如果没有,reinterpret_cast(next_ptr( 才能访问下一个元素?

  • 鉴于上述情况,没有。添加__unaligned说明符对于访问采用指向未对齐数据的指针的参数的函数非常有用,例如ILFindLastID

  • 跟进:在不需要时如何删除__unaligned说明符?在包含标头之前使用const_cast或喜欢 Windows:#define __unaligned使用预处理器检查您是否在 x86-64 或其他安全的平台上。

最后

此外,我可以像这样使用 __unaligned 作为模板参数推导的一部分吗?

是的,但是像这样:

template< class T > struct is_aligned_helper : std::true_type {};
template< class T > struct is_aligned_helper<__unaligned T> : std::false_type {};
template< class T > struct is_aligned : is_aligned_helper<typename std::remove_cv_t<std::remove_pointer_t<T>>> {};

您需要先删除指针以检查指向数据的类型。然后删除任何常量或易失性以获得裸类型 +__unaligned(如果存在(。

在Visual C++中,引入__unaligned关键字只是为了支持英特尔安腾(_M_IA64(,这需要对未对齐的读取进行特殊处理。

WindowsServer 2008 R2和 WindowsXP x64 Edition是支持 Itanium 的 Windows 的最后一个版本。

这不适用于 x86、x64、ARM 或 ARM64 上的 Windows。

简而言之,不要在代码中使用它。

查看Microsoft文档