Linux 上的 unistd.h 和 c99

发布于 2024-09-11 10:54:32 字数 585 浏览 6 评论 0原文

这个简单的 .c 文件:

#include <unistd.h>

void test() {
   char string[40];
   gethostname(string,40);
}

... 正常编译时,工作正常:

$ cc  -Wall -c -o tmp.o tmp.c
$

... 但在 C99 模式下编译时,给出警告:

$ cc -Wall -std=c99 -c -o tmp.o tmp.c 
tmp.c: In function `test':
tmp.c:5: warning: implicit declaration of function `gethostname'
$

生成的 .o 文件很好,并且链接有效。我只是想摆脱这个警告。我可以通过将声明放入我自己的 .h 文件中,以一种 hacky 的方式实现这一点。

C99 中的什么问题导致 unistd.h 中的声明不被包含在内? 可以在不放弃 C99 优点的情况下克服这个问题吗?

我发现其他标准库也存在同样的问题。

This simple .c file:

#include <unistd.h>

void test() {
   char string[40];
   gethostname(string,40);
}

... when compiled normally, works fine:

$ cc  -Wall -c -o tmp.o tmp.c
$

... but when compiled in C99 mode, gives a warning:

$ cc -Wall -std=c99 -c -o tmp.o tmp.c 
tmp.c: In function `test':
tmp.c:5: warning: implicit declaration of function `gethostname'
$

The resultant .o file is fine, and linking works. I'd just like to get rid of the warning. I can achieve this in a hacky way, by putting declarations in my own .h file.

What is it about C99 that means the declarations in unistd.h don't get included?
Can this be overcome, without giving up the niceness of C99?

I see the same problem for other standard libs.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

拍不死你 2024-09-18 10:54:32

获取 gethostname() 的原型

您可能需要以特定方式定义一些宏,以从 man gethostname

功能测试宏要求
glibc(参见 feature_test_macros(7)):

 gethostname(): _BSD_SOURCE || _XOPEN_SOURCE >= 500
   设置主机名():_BSD_SOURCE || (_XOPEN_SOURCE && _XOPEN_SOURCE < 500)

所以:

#define _BSD_SOURCE

#include <unistd.h>

void test() {
   char string[40];
   gethostname(string,40);
}

血淋淋的细节:

如果您没有指定 -std-c99 选项,则 features.h (这是隐式的由 unistd.h 包含)将默认设置 _BSD_SOURCE,以便包含 gethostname() 的原型。但是,指定 -std=c99 会导致编译器自动定义 __STRICT_ANSI__,进而导致 features.h 不定义 _BSD_SOURCE,除非您使用自己的功能宏定义强制它(如上所述)。

You may need to define some macros in a particluar way to get the prototype for gethostname()

From man gethostname:

Feature Test Macro Requirements for
glibc (see feature_test_macros(7)):

   gethostname(): _BSD_SOURCE || _XOPEN_SOURCE >= 500
   sethostname(): _BSD_SOURCE || (_XOPEN_SOURCE && _XOPEN_SOURCE < 500)

So:

#define _BSD_SOURCE

#include <unistd.h>

void test() {
   char string[40];
   gethostname(string,40);
}

The gory details:

If you don't specify the -std-c99 option, then features.h (which is implicitly included by unistd.h) will default to setting _BSD_SOURCE in such a way that the prototype for gethostname() gets included. However, specifying -std=c99 causes the compiler to automatically define __STRICT_ANSI__, which in turn causes features.h to not define _BSD_SOURCE, unless you force it with your own feature macro definition (as above).

还在原地等你 2024-09-18 10:54:32

gethostname( ) 不是标准 C 函数(C99 标准中没有提及),因此在编译到标准时未正确定义该符号。

如果您使用的是 gcc 工具链,请使用 -std=gnu99,您将获得您想要的行为。

或者,查看 ,似乎您可以使用 -D_GNU_SOURCE-D_XOPEN_SOURCE=500 来获得所需的行为。

gethostname( ) is not a standard C function (it's not mentioned anywhere in the C99 standard), so the symbol is correctly not defined when compiling to the standard.

If you're using the gcc toolchain, use -std=gnu99 and you'll get the behavior you want.

Alternatively, looking at <features.h>, it seems like you could use -D_GNU_SOURCE or -D_XOPEN_SOURCE=500 to get the desired behavior.

携君以终年 2024-09-18 10:54:32

阅读man gethostname。在功能测试宏要求中,需要 _BSD_SOURCE(或 _XOPEN_SOURCE>500)从 unistd.h 中提取 gethostname。

接下来阅读man feature_test_macros。您会发现 -std=c99 打开 __STRICT_ANSI____STRICT_ANSI__ 关闭 _BSD_SOURCE。这意味着您无法从 unistd.h 获取 gethostname,除非您再次定义 _BSD_SOURCE。对于大多数情况,我通常将 _GNU_SOURCE 放在命令行上(即 gcc -D_GNU_SOURCE -std=c99 file.c),这也会打开 _BSD_SOURCE

PS 手册页包含一个示例程序,可以打印当前的 ft 宏。您可以针对某些编译器设置编译并运行它。

Read man gethostname. It says in the Feature Test Macro Requirements, that _BSD_SOURCE (or _XOPEN_SOURCE>500) is required to pull gethostname from unistd.h.

Next read man feature_test_macros. You will find that -std=c99 turns on __STRICT_ANSI__ which in turns off _BSD_SOURCE. This means you can't get gethostname from unistd.h unless you define _BSD_SOURCE again. I usually place _GNU_SOURCE on my command line (i.e. gcc -D_GNU_SOURCE -std=c99 file.c) for most things, which turns on _BSD_SOURCE as well.

P.S. The manual page contains an example program which can print the current ft-macros. You might compile and run it for some compiler settings.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文