__unaligned说明符何时与指针一起使用?
When is the __unaligned specifier used with pointers?
>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文档
- 如何将enable-if与模板参数和参数包一起使用
- 如何将PERF_AMPLE_READ与mmap一起使用
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 如何将C++中的库和头与MinGW一起使用
- 将--whole archive链接器选项与CMake和具有其他库依赖项的库一起使用
- 为什么我不能将 rand() 与数组的大小一起使用?
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 不能将复制初始化与隐式转换的多个步骤一起使用
- 将fold表达式与std::一起用于两个元组
- spdlog标头仅与外部fmt一起使用.spdlog错误:'内部':不是'fmt'
- 将 std::allocate_shared 与多态资源分配器一起使用
- 为什么常量词在重载运算符中不与 ostream 对象一起使用<<?
- 将 OpenCV 与 CMAKE 中的项目一起构建为第三方库的正确方法
- 将 exprtk 与自定义类的对象一起使用
- 将 std::set 与基于键的比较器一起使用
- 将 C++ 类与 Rcpp 一起使用,从 C 或 R 修改它
- 如何将 Eigen::Ref 与 pybind11 一起使用?
- 如何将AERT_Allocate与 std:vector 一起使用
- 如何使我的 sizeof sum 结构与空参数包一起工作
- 在将 new 与指针一起使用时,创建数组的指定长度