是intptr_t是uintptr_t的签名副本(反之亦然)吗? [英] Is intptr_t a signed counterpart of uintptr_t (and vice versa)?

查看:120
本文介绍了是intptr_t是uintptr_t的签名副本(反之亦然)吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为add_signed MPL类开发一些测试,将类型转换为其签名对应。它定义如下:

 模板< class T> 
struct add_signed {
typedef T type;
};

模板<>
struct add_signed< std :: uint8_t> {
typedef std :: int8_t type;
};

模板<>
struct add_signed< std :: uint16_t> {
typedef std :: int16_t type;
};

模板<>
struct add_signed< std :: uint32_t> {
typedef std :: int32_t type;
};

模板<>
struct add_signed< std :: uint64_t> {
typedef std :: int64_t type;
};

在测试不同类型时,我注意到以下值为true:

  std :: is_same< add_signed< uintptr_t> :: type,intptr_t> :: value // true 
/ pre>

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

 code> std :: is_same< add_unsigned< intptr_t> :: type,uintptr_t> :: value // true 

我的编译器是MSVC 2010。



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

解决方案

类型 intptr_t 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 步骤来救援:它要求对象指针和函数指针的大小相同。 p>


2.12.3指针类型



所有函数指针类型都应具有相同的表示形式类型指针指向 void 。将函数指针转换为 void * 不得更改表示。从这种转换产生的 void * 值可以转换回原始函数指针类型,使用显式转换,而不会丢失信息。



注意:



ISO C标准不需要这一点,但它是POSIX一致性所必需的。



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 to void * shall not alter the representation. A void * 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.

这篇关于是intptr_t是uintptr_t的签名副本(反之亦然)吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆