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、おそらくintまたはlong) であるため、

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 longULL定数の後に入れてみてください。

それを行う別の方法は です(unsigned long long) 1000000。乗算のオペランドの少なくとも 1 つにこれがある限り、結果が優先順位の高い型になることが保証されます。暗黙的な型変換の優先順位規則は次のとおりです (最高から最低の順)。

long double=> double=> float=> unsigned long long=> long long=> unsigned long=> long=> unsigned int=>int

于 2013-01-09T17:19:12.480 に答える