在运行为MIPS编译的程序时,我偶然发现了一个非常奇怪的问题。
以下代码片段是获取时间纪元并将其以微秒精度存储在unsigned long long
变量中。
该变量能够存储我用sizeof(unsigned long long)
检查的8个字节。
这段代码打印出来很奇怪:
unsigned long long microtime=0;
struct timeval time_camera = { .tv_sec=0, .tv_usec=0 };
gettimeofday(&time_camera,NULL);
microtime = time_camera.tv_sec * 1000000 + time_camera.tv_usec;
printf("Times is now %llu , time since epoch in seconds is: %lu\n", microtime, time_camera.tv_sec);
它给了我以下输出:
>> Times is now 484305845 , time since epoch in seconds is: 1357751315
但是,当我将计算分解为不同的行时,它会起作用! :
unsigned long long microtime=0;
struct timeval time_camera = { .tv_sec=0, .tv_usec=0 };
gettimeofday(&time_camera,NULL);
microtime = time_camera.tv_sec;
microtime = microtime * 1000000;
microtime = microtime + time_camera.tv_usec;
printf("Times is now %llu , time since epoch in seconds is: %lu\n", microtime, time_camera.tv_sec);
输出是:
Times is now 1357751437422143 , time since epoch in seconds is: 1357751437
现在这只是一个巧合吗?例如,我已经损坏了内存或实际上超过了它吗?也许这是MIPS编译器?任何帮助表示赞赏!
答案 0 :(得分:9)
microtime = time_camera.tv_sec * 1000000 + time_camera.tv_usec;
tv_sec
是一个较小的整数类型(time_t
,可能是int
或long
),所以
time_camera.tv_sec * 1000000
溢出。使用后缀为常量提供适当的类型
time_camera.tv_sec * 1000000ULL
在
microtime = time_camera.tv_sec;
microtime = microtime * 1000000;
乘法在unsigned long long
执行,因为一个操作数(microtime
)已经具有该类型,因此另一个操作数转换为该类型。
答案 1 :(得分:4)
在您分配到size_t
之前,您似乎正在进行unsigned long long
数学运算。尝试将ULL
放在常数之后。
另一种方法是(unsigned long long) 1000000
。只要在乘法中至少有一个操作数上有这个,就可以确定结果将是更高优先级的类型。隐式类型转换优先级规则是(按从高到低的顺序):
long double
=> double
=> float
=> unsigned long long
=> long long
=> unsigned long
=> long
=> unsigned int
=> int