Почему gcc не может найти интерфейс random(), когда установлено значение -std=c99?
Вопрос
Я знаю "#include <stdlib.h>"
в верхней части источника.
Пример компиляции:
/usr/bin/colorgcc -std=c99 -fgnu89-inline -g -Wall -I/usr/include -I./ -I../ -I../../ -I../../../ -I../../../../ -O3 -o f8 f8.c
In file included from f8.c:7:
ctype-cmp.c: In function ‘randomized’:
ctype-cmp.c:48: warning: implicit declaration of function ‘random’
ctype-cmp.c: In function ‘main’:
ctype-cmp.c:153: warning: implicit declaration of function ‘srandom’
ais@xcalibur:t$
Когда я выключаю -std=c99, функция isfinite() не может быть найдена.Поэтому я действительно хочу использовать -std=c99 по этой и другим причинам.Есть ли какой-то трюк, который я упускаю?
Решение
man srandom
говорит, что функция является не часть C99, но часть POSIX.
Активировать _BSD_SOURCE
или _XOPEN_SOURCE >= 500
или любой другой подходящий макрос тестирования функции, который объявляет функцию srandom / random (см. man feature_test_macros
и man srandom
).
У этого есть хорошие шансы, но вам нужно выяснить макросы, которые определены / не определены неявно, таким образом, тоже, прочитав справочные страницы выше.
/usr/bin/colorgcc -std=c99 -D_XOPEN_SOURCE=600 -fgnu89-inline -g -Wall
-I/usr/include -I./ -I../ -I../../ -I../../../ -I../../../../ -O3 -o f8 f8.c
Другие советы
Да, есть один трюк, которого вам не хватает:вы можете использовать -std=gnu99
вместо того , чтобы -std=c99
.
-std=c99
#define
s __STRICT_ANSI__
, который /usr/include/features.h
интерпретируется как "по умолчанию не включать ничего, выходящего за рамки стандарта C" (без этого вы получаете, по крайней мере, оба _SVID_SOURCE
и _BSD_SOURCE
). -std=gnu99
, с другой стороны, означает "C99 плюс расширения GNU" (gcc по умолчанию в настоящее время -std=gnu89
, его эквивалент C89, именно поэтому вам нужно было что-то указать, чтобы получить новые функции C99).
В качестве альтернативы вы можете включить макросы тестирования функций (как упомянуто в ответе @litb).Глядя на /usr/include/stdlib.h
в моей системе он ожидает одного из __USE_SVID
, __USE_XOPEN_EXTENDED
, или __USE_BSD
. /usr/include/features.h
говорит мне, что макросами для тестирования функций, которые позволили бы это сделать, являются:
_SVID_SOURCE
(позволяет__USE_SVID
)_BSD_SOURCE
(позволяет__USE_BSD
)_XOPEN_SOURCE
со значением не менее500
(позволяет__USE_XOPEN_EXTENDED
)_XOPEN_SOURCE_EXTENDED
(также позволяет__USE_XOPEN_EXTENDED
)_GNU_SOURCE
(включает все, включая четыре макроса для тестирования функций, описанные выше)
Для новых программ, где вы не слишком обеспокоены потенциальными конфликтами имен с новыми функциями из будущих стандартов, используйте оба -std=gnu99
и -D_GNU_SOURCE
это хорошая идея.Это позволяет вам использовать все новые стандартные функции и расширения GNU, которые в сочетании с каким-либо резервным вариантом (например, autoconf
-тесты функций стиля) обеспечивает наибольшую гибкость.
Ссылки:
Я создал случайные числа, используя gcc в CodeBlocks под Ubuntu 9.10 (с параметрами компилятора: -std=gnu99 -D_GNU_SOURCE
) Так что у меня это сработало:
Это мой код, с которым я играл:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
enum computer {keyboard, CPU, screen, printer};
int main(void)
{
enum computer comp;
time_t casovac;
comp = CPU;
srand(&casovac);
printf("%d", rand());
return 0;
}
Это была всего лишь идея, конечно, вы можете выполнить это другими способами ;-) [Для установки CodeBlocks используйте: sudo apt-get install build-essential
и тогда sudo apt-get install codeblocks
]
Я использую rand() и srand().КСТАТИ:Вы забыли один или два заголовка?По крайней мере, второе предупреждение говорит мне об этом.
Попробуйте включить math.h.(Просто вспомнил, что у нас всегда были проблемы с математической библиотекой, и нам приходилось фактически принудительно связывать ее с -lm).