Подтвердить что ты не робот

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).

4b9b3361

Ответ 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> соответственно.