When is the __unaligned specifier used with pointers?

Solution 1:

Simply: when should the __unaligned specifier be used when dealing with pointers to potentially unaligned data?

  • In short, when the platform you are using demands it, e.g. the Windows API on x86-64. It's a legacy throwback to Itanium and not a concern on x86-32. Some other processors also have issues with unaligned data (e.g. MIPS).

  • Specifically, the __unaligned specifier simply means data may not be on an aligned boundary. It has no meaning outside of a pointer type.

  • On 32 bit x86 platforms, Windows itself simply declares #define __unaligned.

Do I then need to check if the new address is aligned, and if not, reinterpret_cast(next_ptr) to access the next element?

  • Given the above, no. Adding the __unaligned specifier is useful to access functions that take arguments that are pointers to unaligned data, such as ILFindLastID.

  • Followup: How do you remove the __unaligned specifier when unneeded? Use const_cast or do like Windows: #define __unaligned before including a header. Use preprocessor checks that you are on x86-64 or another platform where this is safe.

Lastly,

Further, can I use __unaligned as part of template argument deduction in a manner similar to const, like so?

Yes, but like this:

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>>> {};

You need to remove the pointer first to check the type of the pointed to data. Then remove any const or volatile to get the bare type + __unaligned (if present).