Can -std = c99 предотвращает правильную работу #includes?
Я пытаюсь скомпилировать C-программу в системе Linux. У меня есть оператор #include
для stdlib.h
.
Когда я скомпилирую программу с помощью gcc
следующим образом:
gcc -std=c99 -g -o progfoo progfoo.c progbar.c
Я получаю предупреждения о Implicit declaration of function [srand48, drand48, bzero, or close]
.
Компиляция вместо:
gcc -g -o progfoo progfoo.c progbar.c
не дает мне предупреждений, но он кричит о моем использовании циклов for
(что было основанием для добавления -std=c99
в первую очередь).
Учитывая, что man srand48
упоминает, в том числе <stdlib.h>
, что у меня есть, я не уверен, что еще проблема может быть. Петли for
не важны ни для чего (они просто должны были сэкономить время при инициализации массива), поэтому у меня нет проблем с их удалением, но прежде чем я это сделаю, я хотел бы подтвердить, что стандарт c99
заменяет некоторые аспект моих операторов #include
.
Я использую gcc 4.1.2-50 (Red Hat)
.
Ответы
Ответ 1
Can -std = c99 предотвращает правильную работу #includes?
Нет, но они могут выявить ограничения в ваших знаниях о том, как они работают: -)
Хотя функции [sd]rand48
имеют прототип в stdlib.h
, они находятся внутри #ifdef
, по крайней мере, в моей системе:
#if defined __USE_SVID || defined __USE_XOPEN
Поэтому вам, вероятно, придется явно установить один из этих макросов.
Однако перед тем, как попробовать, имейте в виду, что он не работает. Это потому, что весь этот материал управляется макросами gcc
.
Там очень сложный набор правил, используемых для включения или отключения определенных функций в features.h
, и созданные там макросы управляют тем, что заголовочные файлы включают и исключают. Варианты __USE_*
очищаются и устанавливаются в этом файле заголовка на основе других макросов, предоставленных вами.
Например, чтобы установить __USE_SVID
, чтобы вы могли использовать srand48
, вам необходимо предоставить компилятору параметр -D_SVID_SOURCE
.
Но, возможно, более простой способ - просто использовать C99 с расширениями GNU. Для этого замените -std=c99
на -std=gnu99
.
И, для bzero
и close
, они могут быть получены из strings.h
и unistd.h
соответственно.
Сначала я немного смутился о том, почему они скомпилированы с -std=c99
, когда они абсолютно не связаны с C99, но потом я понял, что флаг управляет только тем, что дают вам стандартные заголовки C.
Ни strings.h
(обратите внимание на множественное имя, это не string.h
), а unistd.h
являются частью ISO C.
Ответ 2
Похоже, что функции, которые вы используете, не являются ISO C99, поэтому, когда вы запрашиваете
строгое соблюдение C99, они не будут видны.
Информация здесь: https://bugzilla.redhat.com/show_bug.cgi?id=130815
Флаг -D_POSIX_C_SOURCE=200809L
должен работать.
Смотрите также этот вопрос: Почему gcc не может найти интерфейс random(), когда установлен -std = c99?
Ответ 3
Ошибка, которую вы получаете, звучит так, как будто функции, которые вы используете, не объявляются. Вы уверены, что используете для них правильные заголовки?
Кроме того, использование -std=c99
может отключить некоторые расширения, которые не являются частью стандарта. Ни одна из функций, которые вы упомянули, не является частью стандарта C. Если вы не можете найти для них отдельные заголовки, вы можете попробовать -std=gnu99
.
Ответ 4
-std=c99
заставляет заголовки пропускать все, что может столкнуться с использованием имен за пределами зарезервированного пространства имен C99, включая все стандартные функции POSIX. Портативный способ запросить заголовки дает вам интерфейсы POSIX, чтобы определить _POSIX_C_SOURCE
значение, соответствующее желаемой версии POSIX. Для последней версии POSIX (2008) это означает:
#define _POSIX_C_SOURCE 200809L
или в командной строке:
-D_POSIX_C_SOURCE=200809L
Изменить: Кажется, что функции, которые вы хотите, находятся не в базе POSIX, а в опции XSI, поэтому вы должны определить _XOPEN_SOURCE
для соответствующего значения (700
является последним), чтобы взять их. Это также можно сделать из командной строки или исходных файлов (но если из исходных файлов это должно быть сделано до, включая любые системные заголовки.
Ответ 5
Неявные объявления (где предполагается, что необъявленная функция возвращается int) больше не разрешены на C99.
Тем не менее, gcc не отменяет компиляцию.
Попробуйте включить strings.h
для bzero
, см. также ответ paxdiablo.
Ответ 6
Вы запрашиваете соответствие стандартов, а C99 не определяет srand48()
как функцию, предоставляемую <stdlib.h>
.
Для библиотеки GNU C вы можете запросить дополнительные функции, указав один или несколько параметров, перечисленных в комментарии вверху /usr/include/features.h
, либо #define
до #include
, либо с помощью -D
флаг gcc
.
Для srand48()
(и drand48()
) вы, вероятно, захотите либо -D_XOPEN_SOURCE=500
, либо -D_SVID_SOURCE
(или #define _XOPEN_SOURCE 500
и т.д. в исходных файлах).
bzero()
и close()
должны работать даже с -std=c99
, если вы #include
документированные файлы заголовков для них, которые <strings.h>
и <unistd.h>
соответственно.