1

在运行为 MIPS 编译的程序时,我偶然发现了一个非常奇怪的问题。以下代码片段用于获取时间纪元并将其以微秒精度存储在unsigned long long变量中。

该变量能够存储我检查过的 8 个字节sizeof(unsigned long long)

这段代码奇怪地打印出来:

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 编译器?任何帮助表示赞赏!

4

2 回答 2

9
microtime = time_camera.tv_sec * 1000000 + time_camera.tv_usec;

tv_sec是一个较小的整数类型(time_t,可能是intlong),所以

time_camera.tv_sec * 1000000

溢出。使用后缀为常量赋予适当的类型

time_camera.tv_sec * 1000000ULL

microtime = time_camera.tv_sec;
microtime = microtime * 1000000;

乘法在 处执行unsigned long long,因为一个操作数 ( microtime) 已经具有该类型,因此另一个被转换为该类型。

于 2013-01-09T17:19:34.280 回答
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

于 2013-01-09T17:19:12.480 回答