I'm developing some tests for the add_signed MPL class that converts the type to its signed counterpart. It is defined as follows:
template<class T>
struct add_signed {
typedef T type;
};
template<>
struct add_signed<std::uint8_t> {
typedef std::int8_t type;
};
template<>
struct add_signed<std::uint16_t> {
typedef std::int16_t type;
};
template<>
struct add_signed<std::uint32_t> {
typedef std::int32_t type;
};
template<>
struct add_signed<std::uint64_t> {
typedef std::int64_t type;
};
While testing on different types I noticed that the following evaluates to true:
std::is_same<add_signed<uintptr_t>::type, intptr_t>::value // true
Similarly for the add_unsigned MPL class, the following code evaluates to true:
std::is_same<add_unsigned<intptr_t>::type, uintptr_t>::value // true
My compiler is MSVC 2010.
So the question is - can we assume that in all (sane) compilers signing intptr_t will produce uintptr_t and vice versa?
The types intptr_t
and uintptr_t
are optional in ISO/IEC 9899:1999 (C99), but where one is implemented, so is the other. All signed types have an unsigned counterpart of the same size, and vice versa.
§7.18.1 Integer types
When typedef names differing only in the absence or presence of the initial
u
are defined, they shall denote corresponding signed and unsigned types as described in 6.2.5; an implementation providing one of these corresponding types shall also provide the other....
§7.18.1.4 Integer types capable of holding object pointers
The following type designates a signed integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer:
intptr_t
The following type designates an unsigned integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer:
uintptr_t
These types are optional.
Note that within the meaning of the C standard, functions are not objects; it is not guaranteed by the C standard that uintptr_t
can hold a function pointer.
Fortunately, POSIX steps to the rescue: it does require that object pointers and function pointers are the same size.
2.12.3 Pointer Types
All function pointer types shall have the same representation as the type pointer to
void
. Conversion of a function pointer tovoid *
shall not alter the representation. Avoid *
value resulting from such a conversion can be converted back to the original function pointer type, using an explicit cast, without loss of information.Note:
The ISO C standard does not require this, but it is required for POSIX conformance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With