unistd.h и c99 в Linux - PullRequest
       4

unistd.h и c99 в Linux

11 голосов
/ 28 июля 2010

Этот простой .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 не включаются? Можно ли это преодолеть, не отказавшись от милости C99?

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

Ответы [ 3 ]

17 голосов
/ 28 июля 2010

Вам может потребоваться определить некоторые макросы определенным образом, чтобы получить прототип для 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, если только вы не форсируете его своим собственным определением макроса функции (как описано выше).

10 голосов
/ 28 июля 2010

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

Если вы используете gcc набор инструментов, используйте -std=gnu99, и вы получите желаемое поведение.

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

4 голосов
/ 28 июля 2010

Чтение 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. Страница руководства содержит пример программы, которая может печатать текущие ft-макросы. Вы можете скомпилировать и запустить его для некоторых настроек компилятора.

...