Preamble: I want to convert a pointer to an integer type, e.g. to check alignment. uintptr_t
seems to be the correct type, but it is guaranteed only in C, not in C++ (or C++11)
For the following code:
#include <stdint.h>
#ifndef I_WONDER_IF_UINTPR_T_IS_DEFINED
typedef unsigned long uintptr_t;
#endif
template <typename T>
bool isAligned(unsigned char* p) ///Checks alignment with respect to some data type
{
return !((uintptr_t) p % sizeof(T));
}
template bool isAligned<uint16_t>(unsigned char* p);
template bool isAligned<uint32_t>(unsigned char* p);
template bool isAligned<uint64_t>(unsigned char* p);
2 questions:
I_WONDER_IF_UINTPR_T_IS_DEFINED
?unsigned long
and forget about it?Generated assembly (when uintptr_t available): http://goo.gl/4feUNK
Note 1: I am aware than in C++11 I should use alignof
in place of sizeof
Note 2: I am aware of this discussion: <cstdint> vs <stdint.h>
If you really want to work with an implementation not providing uintptr_t
when including <stdint.h>
, consider using uintmax_t
instead, and a static_assert
for suitability (you already established you might be on a goofy setup, so it might be too small):
#include <stdint.h>
static_assert(sizeof(uintmax_t) >= sizeof(void*), "need a bigger unsigned type.");
// Add code using `uintmax_t` to round-trip data-pointers here
There are two dis-advantages though:
uintmax_t
might not be uintptr_t
, important for overload-resolution and linking.uintmax_t
might be bigger than neccessary.