Some time ago, a friend of mine reported a problem with gettimeofday()
under MinGW. It was a relatively common error: 'gettimeofday' undeclared (first use this function)
. Cause and solution of this problem is kind of easy, and we’ll present it at the end of the post. However, what’s that function gettimeofday()
?
gettimeofday() is a function for retrieving system time in POSIX-compliant systems. Unlike the time() function, which has a resolution of 1 second, gettimeofday()
has a higher resolution: microseconds. Specifically, the prototype of gettimeofday()
is:
int gettimeofday (struct timeval *tp, struct timezone *tzp)
The function retrieves the current time expressed as seconds and microseconds since the Epoch, and stores it in the timeval
structure pointed to by tp
. The struct timeval
has the following members:
long int tv_sec
: Number of whole seconds of elapsed time.
long int tv_usec
: The rest of the elapsed time (a fraction of a second), represented as the number of microseconds.
Thanks to the tv_usec
member, we have a resolution of microseconds. It’s also important to remember what the Epoch is. The Epoch is just an arbitrary starting date set by the system in order to compute time, i.e., it’s a reference or base time. For instance, POSIX-compliant systems measure system time as the number of seconds elapsed since the start of the epoch at 1970-01-01 00:00:00 Z.
On its side, the struct timezone
was used to return information about the time zone. However, using this parameter is obsolete (e.g., it has not been and will not be supported by libc or glibc). Therefore, tzp
should be a null pointer, else the behavior may be unspecified (check your system’s specifications).
gettimeofday()
returns 0 for success, or -1 for fail. Simple. Further, this function should be available in sys/time.h
. But my friend’s installation of MinGW only included the following in sys/time.h
:
#include <windows.h>
#ifndef _TIMEVAL_DEFINED /* also in winsock[2].h */
#define _TIMEVAL_DEFINED
struct timeval {
long tv_sec;
long tv_usec;
};
#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
#define timercmp(tvp, uvp, cmp) \
(((tvp)->tv_sec != (uvp)->tv_sec) ? \
((tvp)->tv_sec cmp (uvp)->tv_sec) : \
((tvp)->tv_usec cmp (uvp)->tv_usec))
#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
#endif /* _TIMEVAL_DEFINED */