I'm trying to measure the amount of time an operation is taking, as accurately as possible. My research led me to believe that clock_gettime()
and friends is what I want.
However, I can't for the life of me get it to work. Consider this seemingly trivial example:
#include <time.h>
#include <unistd.h>
int main(void)
{
struct timespec t;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t);
return 0;
}
If I run that through the preprocessor, everything looks like it's just fine:
$ cpp time.c | tail -n10
# 1163 "/usr/include/unistd.h" 3 4
# 3 "time.c" 2
int main(void)
{
struct timespec t;
clock_gettime(2, &t);
return 0;
}
However, if I try to compile the preprocessed code, it won't:
$ cpp time.c > time-prep.c
$ cc -o time -Wall -std=c11 -lrt time-prep.c
/tmp/user/1000/cc00SdhB.o: In function `main':
time-prep.c:(.text+0x15): undefined reference to `clock_gettime'
collect2: error: ld returned 1 exit status
$
If I try to compile the original, it doesn't go any better:
$ cc -o time -Wall -std=c11 -lrt time.c
time.c: In function ‘main’:
time.c:6:18: error: storage size of ‘t’ isn’t known
time.c:7:2: warning: implicit declaration of function ‘clock_gettime’ [-Wimplicit-function-declaration]
time.c:7:16: error: ‘CLOCK_PROCESS_CPUTIME_ID’ undeclared (first use in this function)
time.c:7:16: note: each undeclared identifier is reported only once for each function it appears in
time.c:6:18: warning: unused variable ‘t’ [-Wunused-variable]
$
The man page for clock_gettime says that I need to
Link with
-lrt
(only for glibc versions before 2.17).
but as you can see, I'm already doing that. Adding or removing -lrt
to cc
doesn't seem to make any difference whatsoever in my case.
I have looked at /usr/include/time.h
but don't see anything obvious that I am missing.
What (presumably trivial) incantation is missing for me to be able to use clock_gettime() in my code?
The Linux documentation for clock_gettime()
specifies a feature-test requirement:
_POSIX_C_SOURCE >= 199309L
You could consider fulfilling that directly, perhaps via a #define
directive at the very beginning of your code, since the code in fact does depend on it.
If you do not provide such a #define
, then gcc
may nevertheless do it for you, depending on the options you specify to it. By default, it will do. Likewise with -std=gnu99
or -std=gnu11
. But you attempted to compile with -std=c11
, which asks for strict(ish) compliance with C11. C11 does not define the needed POSIX feature-test macro.