天天看點

《深入了解C++11:C++ 11新特性解析與應用》——2.3 擴充的整型

類别:部分人

程式員常會在代碼中發現一些整型的名字,比如uint、__int16、u64、int64_t,等等。這些類型有的源自編譯器的自行擴充,有的則是來自某些程式設計環境(比如工作在linux核心代碼中),不一而足。而事實上,在c++11中一共隻定義了以下5種标準的有符号整型:

《深入了解C++11:C++ 11新特性解析與應用》——2.3 擴充的整型

标準同時規定,每一種有符号整型都有一種對應的無符号整數版本,且有符号整型與其對應的無符号整型具有相同的存儲空間大小。比如與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類型後才與(long long)b進行運算。而無論是擴充的整型還是标準的整型,其轉化的規則會由它們的“等級”(rank)決定。而通常情況,我們認為有如下原則:

《深入了解C++11:C++ 11新特性解析與應用》——2.3 擴充的整型
《深入了解C++11:C++ 11新特性解析與應用》——2.3 擴充的整型

而在進行隐式的整型轉換的時候,一般是按照低等級整型轉換為高等級整型,有符号的轉換為無符号。這種規則其實跟c++98的整型轉換規則是一緻的。

在這樣的規則支援下,如果編譯器定義一些自有的整型,即使這樣自定義的整型由于名稱并沒有被标準收入,因而可移植性并不能得到保證,但至少編譯器開發者和程式員不用擔心自定義的擴充整型與标準整型間在使用規則上(尤其是整型提升)存在着不同的認識了。

比如在一個128位的構架上,編譯器可以定義_int128_t為128位的有符号整型(對應的無符号類型為_uint128_t)。于是程式員可以使用_int128_t類型儲存形如+92233720368547758070的超長整數(長于64位的自然數)。而不用檢視編譯器文檔我們也會知道,一旦遇到整型提升,按照上面的規則,比如_int128_t a,與任何短于它的類型的資料b進行運算(比如加法)時,都會導緻b被隐式地轉換為_int128_t的整型,因為擴充的整型必須遵守c++11的規範。

繼續閱讀