您還沒有表現出你的實際代碼
(見下文),但您提供足夠的信息來推斷它:
signed char c = 0x8d << 3;
恆0x8d
是int
類型。將它左移3位將得到值0x468
,或等效地爲1128
。
初始化將該值從int
隱式轉換爲signed char
。由於該值超出範圍signed char
(推測其範圍爲-128
至+127
,除非您的系統非常奇怪),結果是實現定義的。通常,高位被丟棄,這會產生0x68
或104
的結果。
編譯器警告你,你正在將值1128
轉換爲signed char
,這個值不夠大。
也許你期待0x8d
的類型爲signed char
?事實並非如此。表達式的類型幾乎總是由表達式本身決定的,而不是由它出現的上下文決定的。整數常量(十進制,十六進制或八進制)的類型始終爲int
,除非它們超過INT_MAX
的值,該值至少爲32767
(也可能是2147483647
)。 (或者,除非他們有像L
或U
後綴,但是這不是與此有關)。
UPDATE:
你告訴我們你的原始代碼:
signed char testChar = 0x8d << 3;
printf("testChar : %d\n", testChar);
我期望這會產生警告,因爲您用來初始化testChar
的值1128
會導致溢出。存儲在testChar
中的值是實現定義的,但它很可能是104
,即丟棄高位的結果。
如果拆分轉移到一個單獨的任務:
signed char testChar = 0x8d;
testChar = testChar << 3;
然後我期望相同的結果。但值0x8d
太大而無法存儲在signed char
中,因此轉換會生成實現定義的結果 - 最可能是-115
。而負值左移有未定義的行爲 - 但同樣,它可能會產生-920
,當轉換爲signed char
可能會給你104
。
最終,您的問題的解決方案是做一些事情,而不是你想做的事情。值0x8d << 3
將不適合signed char
,任何嘗試使其適合將導致問題。通過調整代碼,你可以設法消除編譯器的警告,但是你仍然在做一些沒有道理的事情。
警告是正確的,您創建一個編譯時間常量,在創建時溢出字符(8位數量)。 – Rumbleweed
@ M.M:對不起,我誤讀了。 –
請更新您的問題,向我們展示您的實際代碼。此外,你說你有警告,但你沒有告訴我們實際存儲的價值。我期望它是'104'。 –