tags:

views:

122

answers:

3

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.

+5  A: 

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.

Stephen Canon
Although I accepted a different answer, `-std=gnu99` is the fix I actually used. Thanks.
slim
Just ran into exactly this problem, and chose to `-std=gnu99` as well.
Cubbi
+5  A: 

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).

Michael Burr
+1 Very thorough treatment.
Stephen Canon
+1 for an answer. -10 for the `#define _BSD_SOURCE`. Please please use `#define _XOPEN_SOURCE 500` or better yet in the build chain: `cc -D_XOPEN_SOURCE=500 ...`. Well, that if any kind of portability is desired.
Dummy00001
As with my reply to Luther -- `man gethostname` on my Red Hat system makes no mention of Feature Test Macro Requirements. Anyone have any idea why?
slim
+1  A: 

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.

Luther Blissett
None of that is in `man gethostname` on my redhat system. What system is yours on? Should I be installing extra manpages?
slim