[英]c++ safeness of code with implicit conversion between signed and unsigned
根據有符號和無符號整數類型之間的隱式轉換規則, 這里和這里討論,當將unsigned int
與int
相加時,signed int
首先轉換為unsigned int
。
例如,考慮以下最小程序
#include <iostream>
int main()
{
unsigned int n = 2;
int x = -1;
std::cout << n + x << std::endl;
return 0;
}
然而,程序的輸出是預期的1: x
首先被轉換為unsigned int
,而n
的和導致整數溢出,給出“正確”的答案。
在前一個代碼中,如果我確定n + x
是正數,我可以假設unsigned int n
和int x
和給出了期望值嗎?
我認為你可以肯定並且它不是實現定義的,盡管當涉及到不使用二進制補碼表示負值的系統時,該語句需要對標准進行一些解釋。
首先,讓我們陳述清楚的事情:無符號積分不會溢出,而是采用模2 ^ nrOfBits值(參見此在線C ++標准草案 ):
6.7.1基本類型
(7)無符號整數應遵守算術模2n的定律,其中n是該特定整數大小的值表示中的位數。
因此,只需將負值nv
正確轉換為無符號整數位模式nv(conv)
,使x + nv(conv)
始終與x - nv
相同。 對於使用二進制補碼的系統的情況,事情是清楚的,因為實際上設計了兩個補碼使得該算法立即起作用。
對於使用其他負值表示的系統,我們必須仔細閱讀標准:
7.8完整轉換
(2)如果目標類型是無符號的,則結果值是與源整數一致的最小無符號整數(模2n,其中n是用於表示無符號類型的位數)。 [注意:在二進制補碼表示中,此轉換是概念性的,並且位模式沒有變化(如果沒有結束)。 -endnote]
正如腳注明確指出的那樣,在二進制補碼表示中,位模式沒有變化,我們可以假設在2s以外的系統補碼中,將發生實際轉換,使得x + nv(conv) == x - nv
。
因此,由於7.8(2),我會說你的假設是有效的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.