unsigned long long behaving odd in C

Refresh

December 2018

Views

609 time

1

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!

2 answers

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) уже имеет такой тип, поэтому другой преобразуется к этому.

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