Может -std = c99 помешать моей #include работать нормально? - PullRequest
16 голосов
/ 04 февраля 2011

Я пытаюсь скомпилировать программу на 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).

Ответы [ 6 ]

12 голосов
/ 04 февраля 2011

Может -std = c99 помешать моим #include работать нормально?

Нет, но они могут показать ограничения в ваших знаниях о том, как они работают:-)


Хотя функции [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.

6 голосов
/ 04 февраля 2011

Похоже, что используемые вами функции не соответствуют ISO C99, поэтому при запросе строгого соответствия C99 они не будут видны.

Информация здесь: https://bugzilla.redhat.com/show_bug.cgi?id=130815

Флаг -D_POSIX_C_SOURCE=200809L должно работать.

См. Также этот вопрос: Почему gcc не может найти интерфейс random (), если задано -std = c99?

3 голосов
/ 04 февраля 2011

Ошибка, которую вы получаете, звучит так, как будто используемые вами функции не объявляются. Вы уверены, что используете правильные заголовки для них?

Кроме того, использование -std=c99 может отключить некоторые расширения, которые не являются частью стандарта. Ни одна из упомянутых вами функций не является частью стандарта C. Если вы не можете найти для них отдельные заголовки, попробуйте -std=gnu99.

2 голосов
/ 04 февраля 2011

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

1 голос
/ 04 февраля 2011

Вы запрашиваете соответствие стандартам, а 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> соответственно.

1 голос
/ 04 февраля 2011

Неявные объявления (где предполагается, что необъявленная функция возвращает int) больше не разрешены в C99.

При этом gcc не прервет компиляцию.

Попробуйте включить strings.h для bzero, см. также ответ Паксдиабло.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...