《深入理解C++11:C++ 11新特性解析与应用》——2.3 扩展的整型

2.3 扩展的整型

类别:部分人

程序员常会在代码中发现一些整型的名字,比如UINT、__int16、u64、int64_t,等等。这些类型有的源自编译器的自行扩展,有的则是来自某些编程环境(比如工作在Linux内核代码中),不一而足。而事实上,在C++11中一共只定义了以下5种标准的有符号整型:

标准同时规定,每一种有符号整型都有一种对应的无符号整数版本,且有符号整型与其对应的无符号整型具有相同的存储空间大小。比如与signed int对应的无符号版本的整型是unsigned int。

在实际的编程中,由于这5种基本的整型适用性有限,所以有时编译器出于需要,也会自行扩展一些整型。在C++11中,标准对这样的扩展做出了一些规定。具体地讲,除了标准整型(standard integer type)之外,C++11标准允许编译器扩展自有的所谓扩展整型(extended integer type)。这些扩展整型的长度(占用内存的位数)可以比最长的标准整型(long long int,通常是一个64位长度的数据)还长,也可以介于两个标准整数的位数之间。比如在128位的架构上,编译器可以定义一个扩展整型来对应128位的的整数;而在一些嵌入式平台上,也可能需要扩展出48位的整型;不过C++11标准并没有对扩展出的类型的名称有任何的规定或建议,只是对扩展整型的使用规则做出了一定的限制。

简单地说,C++11规定,扩展的整型必须和标准类型一样,有符号类型和无符号类型占用同样大小的内存空间。而由于C/C++是一种弱类型语言,当运算、传参等类型不匹配的时候,整型间会发生隐式的转换,这种过程通常被称为整型的提升(Integral promotion)。比如如下表达式:

(int) a + (long long)b

通常就会导致变量(int)a被提升为long long类型后才与(long long)b进行运算。而无论是扩展的整型还是标准的整型,其转化的规则会由它们的“等级”(rank)决定。而通常情况,我们认为有如下原则:


而在进行隐式的整型转换的时候,一般是按照低等级整型转换为高等级整型,有符号的转换为无符号。这种规则其实跟C++98的整型转换规则是一致的。

在这样的规则支持下,如果编译器定义一些自有的整型,即使这样自定义的整型由于名称并没有被标准收入,因而可移植性并不能得到保证,但至少编译器开发者和程序员不用担心自定义的扩展整型与标准整型间在使用规则上(尤其是整型提升)存在着不同的认识了。

比如在一个128位的构架上,编译器可以定义_int128_t为128位的有符号整型(对应的无符号类型为_uint128_t)。于是程序员可以使用_int128_t类型保存形如+92233720368547758070的超长整数(长于64位的自然数)。而不用查看编译器文档我们也会知道,一旦遇到整型提升,按照上面的规则,比如_int128_t a,与任何短于它的类型的数据b进行运算(比如加法)时,都会导致b被隐式地转换为_int128_t的整型,因为扩展的整型必须遵守C++11的规范。

时间: 2025-01-26 17:39:27

《深入理解C++11:C++ 11新特性解析与应用》——2.3 扩展的整型的相关文章

《深入理解C++11:C++ 11新特性解析与应用》——第3章 通用为本,专用为末 3.1 继承构造函数

第 3 章 通用为本,专用为末 C++11的设计者总是希望从各种方案中抽象出更为通用的方法来构建新的特性.这意味着C++11中的新特性往往具有广泛的可用性,可以与其他已有的,或者新增的语言特性结合起来进行自由的组合,或者提升已有特性的通用性.这与在语言缺陷上"打补丁"的做法有着本质的不同,但也在一定程度上拖慢了C++11标准的制定.不过现在一切都已经尘埃落定了.在本章里读者可以看到这些经过反复斟酌制定的新特性,并体会其"普适"的特性.当然,要对一些形如右值引用.移动

深入理解C# 3.x的新特性(1): Anonymous Type

在C#3.0中,引入了一个新的Feature:Anonymous Method,允许我们已Inline的方式来定义Delegate,为Developer在Coding的时候带来了很大的便利.在C#3.0中,我们又有了另一个相似的Feature:Anonymous Type.Anonymous Type允许我们已Inline的方式的创建一个基于未知类型.具有所需数据结构的对象. 一.Anonymous Type Overview  在传统的编程模式中,对象依赖于一个既定的Type,我们只能在Typ

深入理解C# 3.x的新特性(2):Extension Method[上篇]

在C#3.0中,引入了一些列新的特性,比如: Implicitly typed local variable, Extension method,Lambda expression, Object initializer, Anonymous type, Implicitly typed array, Query expression, Expression tree. 个人觉得在这一系列新特性的,最具创新意义的还是Extension method,它从根本上解决了这样的问题:在保持现有Type

深入理解C# 3.x的新特性(2):Extension Method[下篇]

四.Extension Method的本质 通过上面一节的介绍,我们知道了在C#中如何去定义一个Extension Method:它是定义在一个Static class中的.第一个Parameter标记为this关键字的Static Method.在这一节中,我们来进一步认识Extension Method. 和C# 3.0的其他新特性相似,Extension Method仅仅是C#这种.NET Programming Language的新特性而已.我们知道,C#是一种典型的编译型的语言,我们编

深入理解C#3.x的新特性(4):Automatically Implemented Property

深入理解C#3.x的新特性系列在沉寂一个月之后,今天继续.在本系列前3部分中,我们分别讨论了Anonymous Type,Extension Method 和Lambda Expression,今天我们来讨论另一个实用的.有意思的New feature:Automatically Implemented Property. 一.繁琐的private field + public property Definition 相信大家大家已经习惯通过一个private field + public pr

深入理解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

深入理解C# 3.x的新特性系列自开篇以后,已经有两个月了.在前面的章节中,我们先后深入讨论了C# 3.x新引入的一些列新特性:Anomynous Type.Extension Method.Lambda Expression.Automatically Implemented Property,今天我们来讨论本系列的涉及的另外两个简单的Feature: Object Initializer 和 Collection Initializer. 一.           为什么要引入Object

[原创]深入理解C# 3.x的新特性(3):从Delegate、Anonymous Method到Lambda Expression

较之前一个版本,对于C# 3.x和VB 9来说,LINQ是最具吸引力的.基本上很多的新的特性都是围绕着LINQ的实现来设计的.借助Extension Method,我们可以为LINQ定义一系列的Operator.通过Lambda Expression我们可以为LINQ编写更加简洁的查询.我们可以说这些新的特性成就了LINQ,也可以说这些新特性就是为了实现LINQ而产生,但是我们应该明白,对于这些新引入的特性,LINQ并非他们唯一的用武之地,在一般的编程中,我们也可以使用它们. 继上一章,介绍Ex

《深入理解C++11:C++ 11新特性解析与应用》——2.14 本章小结

2.14 本章小结 在本章中,我们可以看到C++11大大小小共17处改动.这17处改动,主要都是为保持C++的稳定性以及兼容性而增加的. 比如为了兼容C99,C++11引入了4个C99的预定的宏.__func__预定义标识符._Pragma操作符.变长参数定义,以及宽窄字符连接等概念.这些都是错过了C++98标准,却进入了C99的一些标准,为了最大程度地兼容C,C++将这些特性全都纳入C++11.而由于标准的更新,C++11也更新了__cplusplus宏的值,以表示新的标准的到来.而为了稳定性

《深入理解C++11:C++ 11新特性解析与应用》——2.9 扩展的friend语法

2.9 扩展的friend语法 类别:部分人 friend关键字在C++中是一个比较特别的存在.因为我们常常会发现,一些面向对象程序语言,比如Java,就没有定义friend关键字.friend关键字用于声明类的友元,友元可以无视类中成员的属性.无论成员是public.protected或是private的,友元类或友元函数都可以访问,这就完全破坏了面向对象编程中封装性的概念.因此,使用friend关键字充满了争议性.在通常情况下,面向对象程序开发的专家会建议程序员使用Get/Set接口来访问类