隐式声明函数usleep

时间:2012-04-07 10:45:48

标签: c usleep

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

但不确定我对上述内容的处理方式?

6 个答案:

答案 0 :(得分:27)

该列表是定义usleep的前提条件。它基本上是一个涉及#define变量的类C表达式,在包含头文件之前必须为真。

头文件本身只会在usleep语句的大量内容中定义#ifdef,开发人员会花时间告诉您需要做什么,以便您不要不得不花费数小时试图弄明白: - )

假设您使用glibc 2.12或更高版本,则意味着您必须:

  • 声明_BSD_SOURCE;或
  • 宣布了其他三件事的复杂组合,我不打算解码。

最简单的解决方法可能只是使用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

参考:

  1. (这是一个循环引用:请参阅我在此答案下的评论):Is there an alternative sleep function in C to milliseconds?
  2. http://man7.org/linux/man-pages/man2/nanosleep.2.html

答案 4 :(得分:1)

Tl; dr

如果需要获取使用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_SOURCEman 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 SU​​S是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之前