C++错误:对 'clock_gettime' 和 'clock_settime' 的引用未定义

170

我对Ubuntu不太熟悉,但是似乎无法使这个工作。在我的学校电脑上它运行良好,我不知道自己做错了什么。我已经检查过 usr/include ,time.h 在那里也很好。下面是代码:

#include <iostream>
#include <time.h>
using namespace std;

int main()
{
    timespec time1, time2;
    int temp;
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
    //do stuff here
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
    return 0;
}

我使用CodeBlocks作为我的IDE进行构建和运行。任何帮助都将非常感谢,谢谢。


你经常需要使用-D_XOPEN_SOURCE=600。另请参见使用-std=c99的GCC抱怨不知道struct timespec - jww
4个回答

302
-lrt 添加到g++命令行的末尾。这会链接librt.so“实时”共享库。

这在我手动编译时是有效的 - 你有什么想法如何在CodeBlocks中自动化它? - naspinski
7
请尝试进入项目 -> 构建选项 -> 链接器设置;然后添加库 rt。 - Dmitry Yudakov
你的建议对我很有效。我对C语言还不熟悉,-lrt是什么作用? - noufal
@noufal 它命令链接器搜索 rt 库并使用它来解析未定义的符号,http://en.wikipedia.org/wiki/Linker_(computing) - Dmitry Yudakov
3
抱歉在这里表现得像个新手,但你能否用一个完整的例子来说明,比如说 g++ -o main -lrt main.cpp 这样的语句对我无效。 - puk
4
尝试在 main.cpp 后面加上 -lrt,共享库的顺序很重要,参见 这个 或者 那个 获取更多细节。 - Dmitry Yudakov

44

例子:

c++ -Wall filefork.cpp -lrt -O2

对于gcc版本4.6.1,-lrt必须在filefork.cpp之后,否则会导致链接错误。

一些较旧的gcc版本不关心位置。


9
谢谢,-lrt没有被放在正确的位置上一直让我很苦恼。这个疯狂(或者说很多人认为是犯罪)的设置有什么动机吗? - Avio
@Avio - 顺序对于历史原因非常重要。编译器过去只是按顺序处理每个参数。由于库是“软”引用,而不是*.o参数中的“硬”引用,因此除非它们先前被引用(即在左侧),否则库函数将被忽略。 - Mark Lakata

37
自glibc 2.17版本开始,不再需要链接库-lrt
clock_*现在是主C库的一部分。 您可以查看glibc 2.17的更改历史记录,其中解释了进行此更改的原因。
+* The `clock_*' suite of functions (declared in <time.h>) is now available
+  directly in the main C library.  Previously it was necessary to link with
+  -lrt to use these functions.  This change has the effect that a
+  single-threaded program that uses a function such as `clock_gettime' (and
+  is not linked with -lrt) will no longer implicitly load the pthreads
+  library at runtime and so will not suffer the overheads associated with
+  multi-thread support in other code such as the C++ runtime library.

如果您决定升级glibc,则可以查看glibc的兼容性跟踪器,以确定是否在使用较新的glibc时会出现任何问题。
要检查系统上安装的glibc版本,请运行以下命令:
ldd --version

当然,如果您使用旧版的glibc(<2.17),那么仍然需要-lrt

27

我遇到了同样的错误。 我的链接器命令中确实包含了正确的rt库-lrt,而且一段时间内它是可以工作的。 重新安装Kubuntu之后,它停止工作了。

一个独立的论坛帖子建议将-lrt放在项目对象文件之后。 将-lrt移到命令末尾解决了我的这个问题,尽管我不知道为什么。


7
引用来自ircnet的twkm:连接器仅维护所需符号的列表。一旦文件的符号被搜索,只有它所需的部分才会被保留,提供的部分则被丢弃,然后移动到下一个文件名称。 因此,从左到右读取文件,但非常健忘。 - domen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接