我发现了一个Bug,当%llu的(0xffffffff + 1)的打印值为0时,见下面的代码:
unsigned long long resTestBad = 0xffffffff + 1; // number of f is 8
printf("resTestBad is %llu, sizeof(unsigned long long) is %ld\n", resTestBad, sizeof(unsigned long long));
将输出:
resTestBad is 0, sizeof(unsigned long long) is 8
我认为输出是错误的,应该输出或者说正确的输出:
resTestBad is 4294967296, sizeof(unsigned long long) is 8
但是下面的代码没有问题:
unsigned long long resTestAgain = 0xfffffffff + 1; // number of f is 8
printf("resTestAgain is %llu, sizeof(unsigned long long) is %ld\n", resTestAgain, sizeof(unsigned long long));
它会输出(我认为是对的):
resTestAgain is 68719476736, sizeof(unsigned long long) is 8
我的.c 文件如下:
#include <stdio.h>
#include <limits.h>
int main(void)
{
int s = 0xfffe;
printf("s is %d\n", s);
unsigned int ww = 0xfffe;
printf("ww is %d\n", ww);
unsigned long long resTestOk = 0xfffffffe + 1;
printf("resTestOk is %llu, sizeof(unsigned long long) is %ld\n", resTestOk, sizeof(unsigned long long));
unsigned long long resTestBad = 0xffffffff + 1;
printf("resTestBad is %llu, sizeof(unsigned long long) is %ld\n", resTestBad, sizeof(unsigned long long));
unsigned long long resTestAgain = 0xfffffffff + 1;
printf("resTestAgain is %llu, sizeof(unsigned long long) is %ld\n", resTestAgain, sizeof(unsigned long long));
unsigned long long resA = 4294967295 + 1;
printf("resA is %llu, sizeof(unsigned long long) is %ld\n", resA, sizeof(unsigned long long));
unsigned long long resTestUUU = 0xffffffffffffff + 1;
printf("resTestUUU is %llu, sizeof(unsigned long long) is %ld\n", resTestUUU, sizeof(unsigned long long));
unsigned long long resH = (0xffffffff+1) / 1024 / 1024 / 1024;
printf("%llu\n", resH);
unsigned long long resD = (4294967296) / 1024 / 1024 / 1024;
printf("%llu\n", resD);
return 0;
}
运行会输出:
s is 65534
ww is 65534
resTestOk is 4294967295, sizeof(unsigned long long) is 8
resTestBad is 0, sizeof(unsigned long long) is 8
resTestAgain is 68719476736, sizeof(unsigned long long) is 8
resA is 4294967296, sizeof(unsigned long long) is 8
resTestUUU is 72057594037927936, sizeof(unsigned long long) is 8
0
4
可能你不相信,我也不相信,所以我录了一个视频来证明我说的。
是cpu的Bug还是VMWare Workstation的Bug?我该如何解决?
正如@rici对另一个问题的回答中所解释的那样,无符号类型是十六进制整数文字的候选者。 0xffffffff
适合
unsigned long
,因此其类型为 unsigned long
,根据您的编译器,它是 32 位。然后将 int
1
转换为 unsigned long
进行加法,导致溢出。最后将unsigned long
0
转换为unsigned long long
,成为resTestBad
的初始值。使用 0xffffffffULL
强制文字从一开始就为
unsigned long long
。(当您添加另一个 f
时,该值不再适合
unsigned long
,因此文字已经具有类型 long long
并且可以工作。)unsigned long long resTestBad = 0xffffffff + 1;
无符号十六进制常量
0xffffffff
可以用
unsigned int
类型的对象表示。所以它的类型是unsigned int
。所以在这个表达中0xffffffff + 1
对
unsigned int
类型的对象使用算术(整数 由于通常的算术转换,常量
1
也会转换为类型 unsigned int
)。结果会出现溢出,因为结果可以用 unsigned int
类型的对象表示。表达式的值为
0
.至于这个声明
unsigned long long resTestAgain = 0xfffffffff + 1;
则十六进制常量
0xfffffffff
不能用unsigned int类型的对象表示(前提是
sizeof( unsigned int )
不大于4
)。如果 sizeof( long int )
等于 8
(并且在您的程序中它确实等于 8
),则该常量可以用 long int
类型的对象表示。所以在这个表达中
0xfffffffff + 1
对于
long int
类型的对象使用算术..并且表达式的结果也可以用这种类型的对象表示。