سؤال

I stumbled across a very odd issue when running a program compiled for MIPS. The following snippet of code is to get the time epoch and store it in microsecond-precision in an unsigned long long variable.

The variable is capable of storing 8 bytes which I checked with sizeof(unsigned long long).

This code prints out weirdly:

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);

It gives me the following output:

>> Times is now 484305845 , time since epoch in seconds is: 1357751315

However, when I break the calculation into different lines, it works! :

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);

Output is:

Times is now 1357751437422143 , time since epoch in seconds is: 1357751437

Now is it just a coincidence that this works ? e.g have I corrupted memory or actually exceeded it somewhere? Perhaps it's the MIPS compilator? Any help is appreciated!

هل كانت مفيدة؟

المحلول

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

tv_sec is a smaller integer type (time_t, probably int or long), so

time_camera.tv_sec * 1000000

overflows. Use a suffix to give the constant the appropriate type

time_camera.tv_sec * 1000000ULL

In

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

the multiplication is performed at unsigned long long, since one operand (microtime) already has that type, so the other is converted to that.

نصائح أخرى

Looks like you just have size_t math going on before you assign to your unsigned long long. try putting ULL after your constants.

Another way to do it is (unsigned long long) 1000000. As long as you have this on at least one of your operands in a multiplication, you can be assured the result will be the higher precedence type. The implicit type conversion precedence rules are (in order of highest to lowest):

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top