以下一段代码: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?求解惑