這個問題首先是由該碼的(不期望的)的結果的啓發:C標準和bitshifts
uint16_t t16 = 0;
uint8_t t8 = 0x80;
uint8_t t8_res;
t16 = (t8 << 1);
t8_res = (t8 << 1);
printf("t16: %x\n", t16); // Expect 0, get 0x100
printf(" t8: %x\n", t8_res); // Expect 0, get 0
但事實證明,這是有意義的:
6.5.7按位移位運算符
約束
每個操作數應具有整數類型
因此最初困惑線等同於:
t16 = (uint16_t) (((int) t8) << 1);
小非直觀IMHO,但至少明確定義。
好,太好了,但我們這樣做:
{
uint64_t t64 = 1;
t64 <<= 31;
printf("t64: %lx\n", t64); // Expect 0x80000000, get 0x80000000
t64 <<= 31;
printf("t64: %lx\n", t64); // Expect 0x0, get 0x4000000000000000
}
//編輯:按照同樣的文字參數如上,下面應該是等價的:
t64 = (uint64_t) (((int) t64) << 31);
//所以我的困惑/ expectation [end_edit]
現在,我們得到了直觀的結果,但不是從我的(文字)閱讀標準中得出的。這種「進一步自動式促銷」何時/如何發生?還是有侷限性的其他地方,一個類型不能被降級(這將使有意義嗎?),在這種情況下,怎麼做推廣規則適用於:
uint32_t << uint64_t
由於標準不說,這兩個參數都提升到INT;這兩個參數是否應該在這裏被提升到相同的類型?
//編輯:
更具體地說,應該怎樣的結果:
uint32_t t32 = 1;
uint64_t t64_one = 1;
uint64_t t64_res;
t64_res = t32 << t64_one;
//結束編輯
,當我們認識到,規範的回答上面的問題得到解決並不要求促銷int
具體,而是要求integer type
,其中uint64_t具有資格。
//澄清編輯:
好了,但現在我很迷茫一次。具體而言,如果uint8_t
是整數類型,那麼它爲什麼完全被提升爲int
?它似乎並不如下面的練習說明了將相關的整型1:
{
uint16_t t16 = 0;
uint8_t t8 = 0x80;
uint8_t t8_one = 1;
uint8_t t8_res;
t16 = (t8 << t8_one);
t8_res = (t8 << t8_one);
printf("t16: %x\n", t16);
printf(" t8: %x\n", t8_res);
}
t16: 100
t8: 0
爲什麼要升級(T8 < < t8_one)的表達,如果uint8_t是一個整數類型? -
僅供參考,我是從ISO/IEC 9899工作:TC9,WG14/N1124 5月6日,2005年如果這是過時,有人也可以提供一個鏈接到一個更新的副本,那也是值得讚賞的。
我不明白你爲什麼說在第二次移位後留下31位...... // –
我很困惑,因爲格雷格是,但預計類型永遠不會自動降級(縮小),只提升(加寬)。 –
通過閱讀標準,t64 =(uint64_t)(((int)t64)<< 31)是一個等價線,在這種情況下,set bit應該丟失爲int截斷。 – Pat