unistd.h и c99 на Linux

этот простой .файл 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-файл.

что такое C99, что означает объявления в unistd.h не включаются? Это можно преодолеть, без отказа красота С99?

Я вижу ту же проблему для других стандартных библиотек.

3 ответов


вам может потребоваться определить некоторые макросы в particluar способ получить прототип для gethostname()

С man gethostname:

требования к макроса теста особенности для glibc (см. feature_test_macros(7)):

   gethostname(): _BSD_SOURCE || _XOPEN_SOURCE >= 500
   sethostname(): _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, если вы не заставите его с вашим собственным определением макроса функции (как указано выше).


gethostname( ) не является стандартной функцией C (она нигде не упоминается в стандарте C99), поэтому символ правильно не определен при компиляции в стандарт.

если вы используете gcc toolchain, используйте -std=gnu99 и вы получите поведение, которое вы хотите.

кроме того, глядя на <features.h>, похоже, вы могли бы использовать -D_GNU_SOURCE или -D_XOPEN_SOURCE=500 чтобы получить желаемое поведение.


читать man gethostname. Он говорит, что в макросов тестирования, что _BSD_SOURCE (или _XOPEN_SOURCE>500) требуется, чтобы вытащить gethostname из unistd.h.

Читать далее man feature_test_macros. Вы найдете это -std=c99 превращается в __STRICT_ANSI__, который в выключается _BSD_SOURCE. Это означает, что вы не можете сделать gethostname С unistd.h если вы не определите _BSD_SOURCE еще раз. Обычно я размещаю _GNU_SOURCE в командной строке (т. е. gcc -D_GNU_SOURCE -std=c99 file.c) для большинства вещей, который включается _BSD_SOURCE Как хорошо.

P. S. В инструкции страница содержит пример программы, который может напечатать текущую фут-макросы. Вы можете скомпилировать и запустить его для некоторых параметров компилятора.