以下一段代碼:ios
#ifndef MAGICTYPE #define MAGICTYPE(FIRST, SECOND) ((FIRST << 16) + SECOND) #endif long getmagictype(unsigned short first, unsigned short second) { long msgtype = MAGICTYPE(first, second); return msgtype; }
a、(FIRST << 16),這裏不會溢出嗎?c++
b、(FIRST << 16) + SECOND 兩個unsigned short相加,不須要考慮溢出嗎?測試
我第一反應是第二個問題不存在,由於c++對+操做符有一個規則,若是操做數類型長度大於int,則提高爲操做數的類型進行+操做。spa
若是操做數類型長度小於+操做符,那麼會被提高爲int進行+操做。能夠測試一下:code
#include <stdio.h> #ifndef MAGICTYPE #define MAGICTYPE(FIRST, SECOND) ((FIRST << 16) + SECOND) #endif int main() { printf("signed short int length : %d\n", sizeof(signed short int)); unsigned short int first = ((1<<16) - 1); unsigned short int second = 2; long msgtype = 0; printf("first is : %x\n", first, first); printf("second is : %x\n", second, second); msgtype = first + second; printf("msgtype is : %lx\n", msgtype, msgtype); return 0; }
結果以下:blog
signed short int length : 2 first is : ffff second is : 2 msgtype is : 10001
關於第一個問題,我測試了幾個場景:get
第一種狀況:編譯器
#include <stdio.h> #include <iostream> #ifndef MAGICTYPE #define MAGICTYPE(FIRST, SECOND) ((FIRST << 16) + SECOND) #endif int main() { unsigned int a=32; int k = 31; printf("((unsigned int)(1)<<32)-1 : %lu\n", ((unsigned int)(1)<<32)-1); printf("((unsigned int)(1)<<a)-1 : %lu\n", ((unsigned int)(1)<<a)-1); printf("((1)<<a) : %lx\n", ((1)<<a)); return 0; }
結果:io
((unsigned int)(1)<<32)-1 : 4294967295 ((unsigned int)(1)<<a)-1 : 0 ((1)<<a) : 1
有這樣的推測:編譯
a、((unsigned int)(1)<<32)-1 : 4294967295的結果是編譯器把(1)<<32轉換成unsigned int 0了,再進行減一。也就是(unsigned int)-1了,結果如上
b、((unsigned int)(1)<<a)-1 : 0中(1)<<a的結果是在運行時計算了,這涉及到移位操做!1<<32對於整形變量已經溢出了,因此這裏的操做結果和機器強相關。
根據已經輸出的結果能夠推測,測試環境機器<<32以後溢出進行循環移位。操做結果又回到了1.最終操做結果就是0了
c、爲了驗證b操做中的推測,又寫了c測試項來證實上述推測
第二種狀況:
#include <stdio.h> #include <iostream> #ifndef MAGICTYPE #define MAGICTYPE(FIRST, SECOND) ((FIRST << 16) + SECOND) #endif int main() { printf("unsigned short int length : %d\n", sizeof(signed short int)); unsigned short int first = ((1<<16) - 1); unsigned short int second = 2; long msgtype = 0; printf("first is : %x\n", first, first); printf("second is : %x\n", second, second); msgtype = (first << 16); printf("msgtype is : %lx\n", msgtype, msgtype); msgtype = MAGICTYPE(first, second); printf("msgtype is : %lx\n", msgtype, msgtype); first = 1; second = ((1<<16) - 1); printf("first is : %x\n", first, first); printf("second is : %x\n", second, second); msgtype = MAGICTYPE(first, second); printf("msgtype is : %lx\n", msgtype, msgtype); return 0; }
測試結果:
unsigned short int length : 2 first is : ffff second is : 2 msgtype is : ffffffffffff0000 msgtype is : ffffffffffff0002 first is : 1 second is : ffff msgtype is : 1ffff
msgtpye爲什麼輸出的不是ff000000呢,爲什麼多出來這麼多個ff?求解惑