This simp开发者_StackOverflowle .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.
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).
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.
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.
精彩评论