簡體   English   中英

intmax_t 和 uintmax_t 是否保證大小相同?

[英]Are intmax_t and uintmax_t guaranteed to be of the same size?

我需要知道intmax_t是否總是與uintmax_t “相同類型”,除了使用補碼而不是無符號值。

或者用正式的術語來說,下面的代碼是否總是在符合標准的編譯器中編譯?

#include <cstdint>

// The important assertion:
static_assert(sizeof(std::uintmax_t) == sizeof(std::intmax_t));
// Less important assertions:
static_assert(UINTMAX_MAX == static_cast<std::uintmax_t>(INTMAX_MAX) * 2 + 1);
static_assert(-static_cast<std::intmax_t>(UINTMAX_MAX / 2) - 1 == INTMAX_MIN);

我對 C++17 特別感興趣。

我知道 C++20 是第一個強制執行二進制補碼的標准版本,但變量的大小對我來說比表示形式更重要。

是的, uintmax_t保證是intmax_t的無符號副本。

來自 C 標准(N1570 7.20.1):

當定義的 typedef 名稱僅在缺少或存在初始u時不同,它們應表示相應的有符號和無符號類型,如 6.2.5 中所述; 提供這些相應類型之一的實現也應提供另一個。

(C++對C標准庫頭文件的描述,簡單參考C。)

6.2.5 第 6 頁:

對於每個帶符號的 integer 類型,都有一個對應的(但不同的)無符號 integer 類型(用關鍵字unsigned指定),它使用相同的存儲量(包括符號信息)並且具有相同的 alignment 要求。

C++ 在這方面類似於 C ( [basic.fundamental]/3 ):

對於每個標准簽名 integer 類型,存在一個對應的(但不同的)標准無符號 integer 類型 [...] 也就是說,每個帶符號的 integer 類型與其對應的無符號 integer 類型具有相同的 object 表示。 同樣,對於每個擴展的有符號 integer 類型,都存在一個相應的擴展無符號 integer 類型,具有相同的存儲量和 alignment 要求。

這意味着intmax_tuintmax_t總是具有相同的大小。

但是,不能保證其他兩個斷言會成立(在 C++20/C23 之前)。

從評論/標題來看,您似乎在問是否需要相同的尺寸; 在這種情況下,簡短的回答是肯定的......長答案......有點:)

引自[basic.fundamental]/3 (C++17 草案 N4713)

對於每個標准的有符號 integer 類型,存在一個對應的(但不同的)標准無符號 integer 類型:“unsigned char”、“unsigned short int”、“unsigned int”、“unsigned long int”和“unsigned long long int” ”,每個都占用相同的存儲量,並且與其對應的簽名 integer 類型具有相同的 alignment 要求。

(強調我的)

這保證了未簽名的版本占用與其簽名的等效版本相同的大小。

話雖這么說,標准[cstdint.syn]只說明:

使用 intmax_t = signed integer 類型

使用 uintmax_t = unsigned integer 類型

[basic.fundamental]/2狀態

標准和擴展簽名 integer 類型統稱為簽名 integer 類型

[basic.fundamental]/3狀態

標准和擴展的unsigned integer類型統稱為unsigned integer類型

因此,從技術上講,編譯器不必將它們實現為相同的類型,因為那是一個實現細節; 但實際上,它們是一樣的。


正如鴨子所指出的,C 標准確實表明在帶有u和沒有u前綴的類型之間必須有對應的版本。 C 標准通過[cstdint.syn]/2引用

我的回答被鴨子證明是不正確的。 謝謝鴨!

https://stackoverflow.com/a/75203111/2027196

我的原始答案以備將來參考:

標准不保證uintmax_tintmax_t具有相同的寬度,但是不存在具有現代 C 編譯器的系統,它們將具有不同的寬度。 甚至可能沒有非現代的 C 編譯器,它們將具有不同的寬度(在沒有證據的情況下斷言與“天空是藍色的”類型 arguments 相同)。

你能得到的最好的是uintmax_tintmax_t按照約定保證寬度相同。 我說“你能得到的最好的”,但我更願意依賴這種保證,而不是依賴編譯器完美地實現其所有邊緣情況 SFINAE 要求或類似要求。

static_assert放在庫的頂部(可能在assumptions.hpp文件中),然后再也不用擔心這個問題了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM