为什么 GCC 声称 clock_gettime() 隐式声明,但预处理器对相关宏非常满意?
Why does GCC claim clock_gettime() implicitly declared, but the preprocessor is perfectly happy with a related macro?
我正在尝试尽可能准确地测量操作所花费的时间。我的研究让我相信 clock_gettime()
和朋友是我想要的。
但是,我一辈子都无法让它工作。考虑这个看似微不足道的例子:
#include <time.h>
#include <unistd.h>
int main(void)
{
struct timespec t;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t);
return 0;
}
如果我 运行 通过预处理器,一切看起来都很好:
$ 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;
}
但是,如果我尝试编译预处理代码,它不会:
$ 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
$
如果我尝试编译原始版本,它并没有变得更好:
$ 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]
$
clock_gettime 的手册页说我需要
Link with -lrt
(only for glibc versions before 2.17).
但如您所见,我已经在这样做了。在我的情况下,将 -lrt
添加或删除到 cc
似乎没有任何区别。
我查看了 /usr/include/time.h
,但没有发现任何明显的遗漏。
为了能够在我的代码中使用 clock_gettime(),我缺少什么(大概是微不足道的)咒语?
clock_gettime()
的 Linux 文档指定了功能测试要求:
_POSIX_C_SOURCE >= 199309L
您可以考虑直接实现它,或许可以通过代码最开头的 #define
指令,因为代码实际上确实依赖于它。
如果您不提供这样的 #define
,那么 gcc
仍然可以为您提供,具体取决于您为其指定的选项。默认情况下,它会做。 -std=gnu99
或 -std=gnu11
也是如此。但是您尝试使用 -std=c11
进行编译,这要求严格(大概)遵守 C11。 C11 未定义所需的 POSIX 功能测试宏。
您可以在_GNU_SOURCE 上方定义任何#include。有一个例子:
$cat ./main.c
// Need for clock_gettime()
// Have to be at the begining of the file
#define _GNU_SOURCE
#include <time.h>
#include <unistd.h>
int main(void)
{
...
}
我正在尝试尽可能准确地测量操作所花费的时间。我的研究让我相信 clock_gettime()
和朋友是我想要的。
但是,我一辈子都无法让它工作。考虑这个看似微不足道的例子:
#include <time.h>
#include <unistd.h>
int main(void)
{
struct timespec t;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t);
return 0;
}
如果我 运行 通过预处理器,一切看起来都很好:
$ 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;
}
但是,如果我尝试编译预处理代码,它不会:
$ 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
$
如果我尝试编译原始版本,它并没有变得更好:
$ 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]
$
clock_gettime 的手册页说我需要
Link with
-lrt
(only for glibc versions before 2.17).
但如您所见,我已经在这样做了。在我的情况下,将 -lrt
添加或删除到 cc
似乎没有任何区别。
我查看了 /usr/include/time.h
,但没有发现任何明显的遗漏。
为了能够在我的代码中使用 clock_gettime(),我缺少什么(大概是微不足道的)咒语?
clock_gettime()
的 Linux 文档指定了功能测试要求:
_POSIX_C_SOURCE >= 199309L
您可以考虑直接实现它,或许可以通过代码最开头的 #define
指令,因为代码实际上确实依赖于它。
如果您不提供这样的 #define
,那么 gcc
仍然可以为您提供,具体取决于您为其指定的选项。默认情况下,它会做。 -std=gnu99
或 -std=gnu11
也是如此。但是您尝试使用 -std=c11
进行编译,这要求严格(大概)遵守 C11。 C11 未定义所需的 POSIX 功能测试宏。
您可以在_GNU_SOURCE 上方定义任何#include。有一个例子:
$cat ./main.c
// Need for clock_gettime()
// Have to be at the begining of the file
#define _GNU_SOURCE
#include <time.h>
#include <unistd.h>
int main(void)
{
...
}