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 файл прекрасен, и соединение работ. Я был бы точно так же, как для избавлений от предупреждения. Я могу достигнуть этого hacky способом, вставив объявления мой собственный.h файл.

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

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

11
задан slim 28 July 2010 в 17:15
поделиться

3 ответа

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

From man gethostname :

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

18
ответ дан 3 December 2019 в 02:29
поделиться

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

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

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

10
ответ дан 3 December 2019 в 02:29
поделиться

Прочтите man gethostname . В требованиях к макросу для тестирования функций указано, что для получения имени хоста из unistd.h требуется _BSD_SOURCE (или _XOPEN_SOURCE> 500 ).

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

4
ответ дан 3 December 2019 в 02:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: