intptr_t是uintptr_t的签名对应物(反之亦然)?

Bar*_*wek 10 c++ metaprogramming c++11

我正在为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;
};
Run Code Online (Sandbox Code Playgroud)

在对不同类型进行测试时,我注意到以下评估结果为true:

std::is_same<add_signed<uintptr_t>::type, intptr_t>::value  // true
Run Code Online (Sandbox Code Playgroud)

类似地,对于add_unsigned MPL类,以下代码的计算结果为true:

std::is_same<add_unsigned<intptr_t>::type, uintptr_t>::value  // true
Run Code Online (Sandbox Code Playgroud)

我的编译器是MSVC 2010.

所以问题是 - 我们可以假设在所有(理智的)编译器中签名intptr_t会产生uintptr_t,反之亦然吗?

Jon*_*ler 19

类型intptr_tuintptr_t在ISO/IEC 9899可选:1999(C99),但其中一个被实现的,所以是其他.所有签名类型都具有相同大小的无符号对应项,反之亦然.

§7.18.1整数类型

当typedef名称仅在缺少或存在初始值u时定义时,它们应表示6.2.5中描述的相应的有符号和无符号类型; 提供这些相应类型之一的实现也应提供另一种.

...

§7.18.1.4能够保存对象指针的整数类型

以下类型指定一个带符号的整数类型,其属性是任何有效的void指针都可以转换为此类型,然后转换回指向void的指针,结果将等于原始指针:

intptr_t
Run Code Online (Sandbox Code Playgroud)

以下类型指定一个无符号整数类型,其属性是任何有效的void指针都可以转换为此类型,然后转换回指向void的指针,结果将等于原始指针:

 uintptr_t
Run Code Online (Sandbox Code Playgroud)

这些类型是可选的.

注意,在C标准的含义内,函数不是对象; C标准不能保证uintptr_t可以保存函数指针.

幸运的是,POSIX采取措施:它确实需要对象指针和函数指针的大小相同.

2.12.3指针类型

所有函数指针类型应与类型指针的表示形式相同void.将函数指针转换为void *不会改变表示.void *可以使用显式强制转换将这种转换产生的值转换回原始函数指针类型,而不会丢失信息.

注意:

ISO C标准不要求这样,但它是POSIX一致性所必需的.