usleep() 和 inet_aton() 定义的奇怪行为
Posted
技术标签:
【中文标题】usleep() 和 inet_aton() 定义的奇怪行为【英文标题】:Weird behavior with defines for usleep() and inet_aton() 【发布时间】:2021-04-11 08:22:09 【问题描述】:我创建了两个模块:files.h
和 connection.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 等效项 [重复]