我正在为 add_signed MPL 类开发一些测试,将类型转换为其签名的对应项。它的定义如下:
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;
};
在对不同类型进行测试时,我注意到以下计算结果为 true:
std::is_same<add_signed<uintptr_t>::type, intptr_t>::value // true
类似地,对于 add_unsigned MPL 类,以下代码的计算结果为 true:
std::is_same<add_unsigned<intptr_t>::type, uintptr_t>::value // true
我的编译器是MSVC 2010。
所以问题是 - 我们是否可以假设在所有(健全的)编译器中签名 intptr_t 都会生成 uintptr_t ,反之亦然?
类型intptr_t
and uintptr_t
在 ISO/IEC 9899:1999 (C99) 中是可选的,但只要实施其中一项,另一项也是可选的。所有有符号类型都有一个相同大小的无符号对应类型,反之亦然。
§7.18.1 整数类型
当 typedef 名称仅因缺少或存在首字母而不同时u
被定义,它们应表示相应的有符号和无符号类型,如 6.2.5 中所述;提供这些对应类型之一的实现也应提供另一个。
...
§7.18.1.4 能够保存对象指针的整数类型
以下类型指定有符号整数类型,其属性为任何有效的
指向 void 的指针可以转换为该类型,然后再转换回指向 void 的指针,
结果将与原始指针进行比较:
intptr_t
以下类型指定无符号整数类型,具有任何有效的属性
指向 void 的指针可以转换为该类型,然后再转换回指向 void 的指针,
结果将与原始指针进行比较:
uintptr_t
这些类型是可选的。
请注意,在 C 标准的含义内,函数不是对象;而是函数。 C 标准不保证uintptr_t
可以保存函数指针。
幸运的是,POSIX救援步骤:它确实要求对象指针和函数指针具有相同的大小。
2.12.3 指针类型
所有函数指针类型应与指向的类型指针具有相同的表示形式void
。将函数指针转换为void *
不得改变代表。 Avoid *
这种转换产生的值可以使用显式转换转换回原始函数指针类型,而不会丢失信息。
Note:
ISO C 标准不要求这样做,但它是 POSIX 一致性所必需的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)