[英]What tools can diagnose C++ portability issues due to plain char signedness?
[英]Issues about the signedness of char
根據標准, char
是否簽名是實現定義的。 這給我帶來了一些麻煩。 以下是一些例子:
1)測試最重要的位。 如果char
已簽名,我可以簡單地將該值與0
進行比較。 如果未簽名,我將該值與128
進行比較。 這兩種簡單方法都不是通用的,適用於這兩種情況。 為了編寫可移植代碼,似乎我必須直接操作這些位,這不是很好。
2)價值分配。 有時,我需要為char
值寫一個位模式。 如果char
是無符號的,則可以使用十六進制表示法輕松完成,例如, char c = 0xff
。 但是當char
簽名時,此方法不適用。 以char c = 0xff
為例。 0xff
超出了signed char
可以容納的最大值。 在這種情況下,標准說c
的結果值是實現定義的。
那么,有沒有人對這兩個問題有好的想法? 關於第二個,我想知道char c = '\\xff'
對於signed和unsigned char
是否正常。
注意:有時需要將明確的位模式寫入字符。 請參閱http://en.cppreference.com/w/cpp/string/multibyte/mbsrtowcs中的示例。
1)測試MSB: (x | 0x7F) != 0x7F
(或reinterpret_cast<unsigned char&>(x) & 0x80
)
2) reinterpret_cast<unsigned char&>(x) = 0xFF;
請注意,如果要將字符占用的內存視為位集合,則繞過與char
類型中任何給定值關聯的特定位模式, reinterpret_cast
是完全合適的。
如果您真的關心signed-ness,只需根據需要將變量聲明為signed char
或unsigned char
。 不需要平台無關的比特伎倆。
實際上你可以做你想做的事而不用擔心簽名。
十六進制描述位模式而不是整數值。 (見免責聲明)
所以對於2.你說你不能分配像這樣的位模式
char c = 0xff
但你真的可以這樣做,簽名與否。
對於1,您可能無法執行“與0比較”技巧,但您仍有幾種方法可以檢查最重要的位。 一種方法是,向右移動7,在左邊移動零,然后檢查它是否等於1.獨立於簽名。
正如Tony D指出的那樣,(x | 0x7F)!= 0x7F是一種更便攜的方式,而不是移位,因為它可能不會以零移位。 類似地,你可以做x&0x80 == 0x80。
當然你也可以做Brian建議的,只使用unsigned char。
免責聲明:Tony指出0x實際上是一個int,當char不能保存值或者char是無符號時,轉換為char是實現定義的。 但是,沒有任何實施會破壞這里的標准。 char c = 0xFF,天氣或未簽名或不簽名,將填補這些位,相信我。 找到一個不這樣做的實現將是非常困難的。
您可以分別使用兩個0x7F
和0xFF
對給定值進行OR和AND來檢測並刪除其signed_ness。
測試MSB的最簡單方法是使其成為LSB: char c = foo(); if ((c>>(CHAR_BIT-1)) & 1) ...
char c = foo(); if ((c>>(CHAR_BIT-1)) & 1) ...
設置特定的位模式有點棘手。 例如,全比特一可能不一定是0xff,但也可能是0x7ff,更實際的是0xffff。 無論如何, ~char(0)
是all-bits-one。 有點不太明顯, char(-1)
也是如此。 如果簽署了char,那就很清楚; 如果無符號,這仍然是正確的,因為無符號類型工作模2 ^ N. 遵循該邏輯, char(-128)
只設置8位,無論char中有多少位或是否有符號。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.