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