usleep() 和 inet_aton() 定义的奇怪行为

Posted

技术标签:

【中文标题】usleep() 和 inet_aton() 定义的奇怪行为【英文标题】:Weird behavior with defines for usleep() and inet_aton() 【发布时间】:2021-04-11 08:22:09 【问题描述】:

我创建了两个模块:files.hconnection.h

files.h 包含在connection.h 中。

files.h 使用 usleep() 函数,connection.h 在各个 .c 文件的某个点使用 inet_aton() 函数。这些函数需要以下定义:

#define _XOPEN_SOURCE 500
#define _POSIX_C_SOURCE 1
#define _GNU_SOURCE

所以,由于files.h 包含在connection.h 中,我认为我可以在files.h 中编写这些定义,但是当我编译时出现以下错误:

connection.c:23:6: 错误:函数‘inet_aton’的隐式声明

所以我决定尝试在 connection.h 而不是 files.h 中编写这些定义,只是为了编译并得到以下错误:

files.c:298:3: 错误:函数‘usleep’的隐式声明

此时,我的下一个选择是在各自的 .c 文件中编写定义来解决这个问题。但是,我在编译时遇到了这个错误:

files.c:302:3: 错误:函数‘usleep’的隐式声明

connection.c:23:6: 错误:函数‘inet_aton’的隐式声明

我不明白这是什么问题。如何同时使用这两个功能?

files.h

#ifndef _FILES_H_
#define _FILES_H_

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>

// ...

#endif

connection.h

#ifndef _CONNECTION_H_
#define _CONNECTION_H_

#define _XOPEN_SOURCE 500
#define _POSIX_C_SOURCE 1
#define _GNU_SOURCE

#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>

#include "files.h"

#include <ctype.h>
#include <pthread.h>


// ...

#endif

【问题讨论】:

您发布的files.h 不包含指定的宏定义。请发帖Minimal, Reproducible Example。 与您的问题无关,但请注意,任何以下划线开头后跟大写字母的符号都是保留的。请参阅this reserved identifier list 中的第 3 点。 定义 _XOPEN_SOURCE 500、_POSIX_C_SOURCE 和 _GNU_SOURCE 之前,包括任何可能使用它们的头文件。 那是我的错,我再次编辑了问题。我描述的问题发生在包含之前的定义中 【参考方案1】:

这似乎是一个订购问题..

当您以这种方式包含时:

#include <unistd.h>   // other includes as well
#define _XOPEN_SOURCE 500
#define _POSIX_C_SOURCE 1
#define _GNU_SOURCE

头文件在没有覆盖定义的情况下被引入。

但是,定义的目的是更改从标头导入的函数/签名! 而且由于 C 是非常线性的,所以顺序很重要..

#define _XOPEN_SOURCE 500
#define _POSIX_C_SOURCE 1
#define _GNU_SOURCE
#include <unistd.h>   // other includes as well

基本上,在包含任何标准头文件之前,首先定义您的请求。

必须在第一次看到标题之前包含这些 - 因此,如果“connection.c”在 connection.h 之前包含某些内容,那么

的第一个包含的定义可能不存在

【讨论】:

【参考方案2】:

感谢您在.c 文件中的建议,我终于解决了这个问题,编写了包含上面的定义。如果我在 .h 文件中的任何位置编写定义,仍然无法正常工作。

files.c

#define _XOPEN_SOURCE 500
#define _POSIX_C_SOURCE 1
#define _GNU_SOURCE

#include "files.h"

connection.c

#define _XOPEN_SOURCE 500
#define _POSIX_C_SOURCE 1
#define _GNU_SOURCE

#include "connection.h"

【讨论】:

您没有提供这些 .c 文件的顶部。在包括 connection.h 或 files.h 之前,我假设您在那里也有几个包含,但我现在只能猜测。请注意,您通常不应该乱定义这些 SOURCE 版本,而是使用适当的构建系统来为您执行此操作。例如 Cmake 或 GNU 自动工具。 .c 文件中的所有包含都包含在它们各自的 .h 文件中,所以我只需要将 .h 文件包含在 .c 文件中。另外我会看看你建议的替代方案,谢谢 当你说它们被包含时我相信你,但一定要检查你是否在 files.h 或 connection.h 之前包含任何系统包含,例如 unistd.h。

以上是关于usleep() 和 inet_aton() 定义的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章

由 Python2 和 Python3 中 socket.inet_aton() 实现不同引发的血案

INET_NTOA 和 INET_ATON 的 PHP 等效项 [重复]

Linux的sleep()和usleep()的使用和区别

相当于 inet_aton 的 windows

在 PHP 中 sleep 和 usleep 的行为是不是不同?

sleep()和usleep()