gcc (GCC) 4.6.3
c89
我正在尝试使用usleep
。但是,我一直收到以下警告:
隐式声明函数usleep
我已添加unistd.h
标头文件。
手册页提到了这件事。但我不确定我理解它:
usleep():
Since glibc 2.12:
_BSD_SOURCE ||
(_XOPEN_SOURCE >= 500 ||
_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) &&
!(_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700)
Before glibc 2.12:
_BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
但不确定我对上述内容的处理方式?
答案 0 :(得分:27)
该列表是定义usleep
的前提条件。它基本上是一个涉及#define
变量的类C表达式,在包含头文件之前必须为真。
头文件本身只会在usleep
语句的大量内容中定义#ifdef
,开发人员会花时间告诉您需要做什么,以便您不要不得不花费数小时试图弄明白: - )
假设您使用glibc
2.12或更高版本,则意味着您必须:
最简单的解决方法可能只是使用gcc -D _BSD_SOURCE
进行编译或放置:
#define _BSD_SOURCE
在您包含提供usleep
的头文件之前,在代码中。
您可能希望在任何包含之前定义这些内容,以防各种头文件之间存在依赖关系。
答案 1 :(得分:19)
这可能有效:在Linux上使用gcc进行编译时添加-std=gnu99
。
示例:
arm-linux-gcc -lpthread -std=gnu99 -o test ArmLinuxDataPipe1.2.1.c
答案 2 :(得分:1)
Using nanosleep() instead worked for me.
相关说明:usleep()自POSIX-2008和 建议改用nanosleep()。
答案 3 :(得分:1)
在代码顶部添加以下内容:
// For `nanosleep()`:
#include <time.h>
#define __USE_POSIX199309
#define _POSIX_C_SOURCE 199309L
然后使用nanosleep()
来创建自己的sleep_us()
函数来休眠一定数量的微秒:
void sleep_us(unsigned long microseconds)
{
struct timespec ts;
ts.tv_sec = microseconds / 1e6; // whole seconds
ts.tv_nsec = (microseconds % 1e6) * 1e3; // remainder, in nanoseconds
nanosleep(&ts, NULL);
}
为了在Linux Ubuntu上编译和运行,我创建了一个 sleep_test.c 文件并使用:
gcc -Wall -g3 -std=c11 -o sleep_test sleep_test.c && ./sleep_test
答案 4 :(得分:1)
如果需要获取使用usleep()
进行编译的旧代码,请将这些行添加到要包含在任何其他库之前的头文件中:
#define _XOPEN_SOURCE 600
#define _POSIX_C_SOURCE 200112L
或将编译器标志-std=c11 -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200112L
添加到您的Makefile中。
这表明环境您的程序使用了this older version of the UNIX API,其中usleep()
未被弃用。
或者,如果确实是新代码,则将usleep()
替换为nanosleep()
,为您的库版本适当设置功能测试宏,并检查您的代码库是否有其他错误。
在Linux上,您可以检查_XOPEN_SOURCE
中库支持的_POSIX_C_SOURCE
和man feature_test_macros
值。
更长的答案:这是怎么回事。
从历史上看,有几种不同的UNIX标准,并且每个人最终想到的最佳实践是让代码指定为其编写的UNIX API版本。程序员通过定义一个功能测试宏来做到这一点。
UNIX最早的分裂之一是在AT&T的System V和加利福尼亚大学的伯克利标准发行版(BSD)之间。由于System V是正式版本,并且其行为已成为默认版本,而BSD Unix是最早的免费软件,并且已在许多大学中使用,因此看到旧代码声明_BSD_SOURCE
比_SVID_SOURCE
更为常见。 _BSD_SOURCE
宏特别尝试在超过40年的时间内启用来自各种不同操作系统的扩展。有时,它甚至可以用作非标准扩展程序的全部。这两个宏均已弃用,并且与当前接受的答案相反,您永远不应在新代码中使用其中任何一个。
在本世纪,有两种UNIX标准:POSIX(已成为IEEE标准)和Open Group(X / Open)提供的Single Unix Specification(SUS)。 X / Open SUS是POSIX的超集,通常是您要编写的内容。过去可以声明许多不同的功能测试宏,以启用这些标准的最新版本,并且仍然支持这些功能以实现向后兼容。您可以在粘贴的条件下看到其中的一些,但是在编写新代码时不必担心它们。现在已经过了一个用于代码检查的宏_XOPEN_SOURCE_EXTENDED
,但是从历史上看,它是从1995年开始选择的SUS版本。
理论上,在任何现代版本的UNIX或Linux上设置的正确功能测试宏为_XOPEN_SOURCE
。您应该查找您的库支持的最新版本号。在实践中,我认为也应该定义_POSIX_C_SOURCE
,以便保证没有其他人可以不一致地设置它并破坏您的代码,这是一种谨慎的防御性编码。您的问题是一个很好的例子:如果您将_XOPEN_SOURCE
设置为向后兼容,但是_POSIX_C_SOURCE
被设置为工具链中其他位置的最新版本,则_POSIX_C_SOURCE
的较高版本将优先并且usleep()
将不起作用。
因此,这些条件的意思是usleep()
不是POSIX函数,而是一次出现在某些类似BSD的OS上,因此在1995年成为SUS。在2008年已弃用。 ,然后选择POSIX或SUS的任何版本,因为此后会主动将其禁用。因此,如果您选择SUS的500或600版本(以及另一个过时的同义词也将其打开),则启用此功能,但如果您选择POSIX或SUS的任何最新版本,则不推荐使用。如果您选择“一切都可以”选项,也将启用它们,但这是个坏主意。
答案 5 :(得分:1)
回答问题:
采用
#define _BSD_SOURCE
或#define _GNU_SOURCE
对于有错误的人
warning: #warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE" [-Wcpp]
# warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE"
^~~~~~~
使用#define _BSD_SOURCE
后,尝试使用
#define _GNU_SOURCE
注意:在包含为您提供usleep()
的标题之前使用,即在包含unistd.h
之前