我目前正在使用长度可变的数组,它们的长度存储在元素的前两个字节中。由于未填充数组,因此单个元素可能未对齐。确保仅第一个元素对齐,并且整个内容以double 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 {};
答案 0 :(得分:0)
在Visual C ++中,引入__unaligned
关键字仅是为了支持Itanium,它需要对未对齐的读取进行特殊处理。这不适用于x86,x64或任何其他平台。
简而言之,根本不要使用它。
请参见MSDN
答案 1 :(得分:0)
简而言之:在处理指向可能未对齐的数据的指针时,应何时使用__unaligned指定符?
简而言之,当您使用的平台需要它时,例如x86-64上的Windows API。这是对Itanium的遗留回溯,而与x86-32无关。其他一些处理器也存在未对齐数据的问题(例如MIPS)。
具体地说,__unaligned
说明符仅表示数据可能不在对齐的边界上。 It has no meaning outside of a pointer type.
在32位x86平台上,Windows本身仅声明#define __unaligned
。
然后我是否需要检查新地址是否对齐,如果不对齐,则需要reinterpret_cast(next_ptr)来访问下一个元素吗?
鉴于上述,不可以。添加__unaligned
说明符对于访问带有参数的函数很有用,这些参数是指向未对齐数据的指针,例如ILFindLastID
。
后续操作:在不需要时如何删除__unaligned指定符?使用const_cast
或类似Windows:#define __unaligned
,然后再添加标题。 使用预处理程序检查您是否在x86-64或其他安全的平台上。
最后,
此外,我是否可以像const这样,将__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>>> {};
您需要先删除指针以检查指向数据的类型。然后删除所有const或volatile,以获取裸类型+ __unaligned
(如果存在)。