簡體   English   中英

為什么對無符號字符的算術運算將它們提升為有符號整數?

[英]Why do arithmetic operations on unsigned chars promote them to signed integers?

許多類似問題的答案都指出,這是由於標准所致。 但是,我無法理解標准制定者做出這一決定的原因。

據我了解, unsigned char不會以 2 的補碼形式存儲值。 因此,我沒有看到假設XOR兩個unsigned chars會產生意外行為的情況。 因此,將它們提升為int似乎是在浪費空間(在大多數情況下)和 CPU 周期。

此外,為什么int 如果一個變量被聲明為unsigned ,顯然unsigned對程序員來說很重要,因此在我看來,升級為unsigned int仍然比int更有意義。

[編輯#1] 如評論中所述,如果int無法充分容納unsigned char中的值,則將升級為unsigned int

[編輯#2]為了澄清這個問題,如果它是關於在int上操作而不是char的性能優勢,那么為什么它在標准中? 這可以作為對編譯器設計人員進行更好優化的建議。 現在,如果有人要設計一個不這樣做的編譯器,那會使他們的編譯器不完全遵守 C/C++ 標准,即使假設這個編譯器確實支持該語言的所有其他必需特性。 簡而言之,我無法弄清楚為什么我不能直接對unsigned chars進行操作,因此將它們提升為ints的要求似乎沒有必要。 你能舉個例子證明這是錯誤的嗎?

您可以在線找到此文檔: 國際標准的基本原理 - 編程語言 - C(修訂版 5.10,2003)

第 6.3 章(第 44 - 45 頁)是關於轉換的

在 K&R 的發布和 C89 的開發之間,integer 提升規則的演進中的實現之間出現了嚴重的分歧。 實現分為兩大陣營,其特征可能是未簽名保留價值保留

當 integer 促銷活動擴大時,這些方法之間的差異集中在unsigned charunsigned short的處理上,但該決定也對常量的類型產生了影響(參見 §6.4.4.1)。

無符號保留方法要求將兩個較小的無符號類型提升為unsigned int 這是一個簡單的規則,並產生一個獨立於執行環境的類型。

如果該類型可以正確表示原始類型的所有值,則值保留方法要求將這些類型提升為signed int ,否則將這些類型提升為unsigned int

因此,如果執行環境將short表示為小於int的東西,則unsigned short變為int 否則它變成unsigned int 兩種方案在絕大多數情況下都給出了相同的答案,並且在使用二進制補碼算法和有符號溢出時的安靜環繞的實現中甚至在更多情況下都給出了相同的有效結果 - 也就是說,在大多數當前實現中。 在這樣的實現中,只有當這兩個條件都為真時,兩者之間的差異才會出現:

  1. 涉及unsigned charunsigned short的表達式產生一個int范圍的結果,其中設置了符號位,也就是說,對這種類型的一元運算,或者另一個操作數是int或更窄的二元運算“ 類型。

  2. 前面表達式的結果在其符號很重要的上下文中使用:

    sizeof(int) < sizeof(long)並且在上下文中必須將其擴展為 long 類型,或者

    • 在該移位被定義為算術的實現中,它是右移位運算符的左操作數,或

    • 它是/、%、<、<=、> 或>= 的操作數。

在這種情況下,就會出現真正的解釋歧義。 結果必須被稱為可疑簽名,因為可以對已簽名或未簽名的解釋進行案例。 每當一個unsigned int在一個運算符中遇到一個有signed int並且有signed int具有負值時,就會出現完全相同的歧義。 在解決這種對抗的模棱兩可方面,這兩種方案都沒有做得更好或更糟。 突然,負的有signed int變成了一個非常大的unsigned int ,這可能令人驚訝,或者這可能正是知識淵博的程序員所需要的。 當然,所有這些歧義都可以通過明智地使用 casts 來避免

探索這個問題的重要成果之一是理解高質量的編譯器可能會很好地尋找這些有問題的代碼並提供(可選的)診斷,並且認真的講師可能會很好地警告程序員隱式類型轉換的問題.

無符號保留規則大大增加了無符號整數與有signed int unsigned int對峙以產生有問題的有符號結果的情況的數量,而價值保留規則則最大限度地減少了這種沖突。 因此,價值保留規則被認為對新手或粗心的程序員更安全。 經過多次討論,C89 委員會決定支持值保留規則,盡管事實上 UNIX C 編譯器已經朝着無符號保留的方向發展。

C89 中的安靜變化

依賴於無符號保留算術轉換的程序將表現不同,可能沒有抱怨。 這被認為是 C89 委員會對當前普遍做法所做的最嚴重的語義更改。

作為參考,您可以在Lundin的這個答案中找到有關更新到 C11 的轉換的更多詳細信息。

暫無
暫無

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

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