С gcc включать строго символы C99, в частности исключая POSIX

Я прохожу курс на C после многолетнего программирования. Мой инструктор не использует машину POSIX, и я недавно был наказан за использование функции index в задании. Я провел некоторое исследование, и я заметил, что, хотя index был ранней частью AT & T Unix и совместим с POSIX, он не является частью стандарта C99. Я бы хотел, чтобы gcc помог мне найти похожие символы. Я компилирую на OSX с gcc 4.2 (не llvm)

Мой первый этап исследования включал в себя уведомление о том, что мой файл string.h обертывает прототип для index в следующей проверке на макросы проверки функций:

#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)

После небольшого рытья я нашел это (в моем /usr/include/sys/cdefs.h):

 /* STRICT  Defining _POSIX_C_SOURCE or _XOPEN_SOURCE restricts the
 *      available APIs to exactly the set of APIs defined by the
 *      corresponding standard, based on the value defined.
 *
 *      A correct, portable definition for _POSIX_C_SOURCE is 200112L.
 *      A correct, portable definition for _XOPEN_SOURCE is 600L.
 */

И так с помощью этой команды gcc:

gcc -D _POSIX_C_SOURCE=200112L -pedantic -Wall -std=c99 -o myExec ./mySource.c

Я получаю достойное предупреждение:

warning: incompatible implicit declaration of built-in function ‘index’

Это меня смущает, и я хочу, чтобы программа также не смогла соединить. Причина, по которой меня это смущает, я читаю на opengroup.org, что определение этого макроса должно показывать символы POSIX, а не скрыть их. Итак, вот мой вопрос в сжатой форме:

Как я могу сделать gcc 4.2 (на OSX 10.6) компилировать и связывать мою программу в среде, которая строго C99 без каких-либо дополнительных символов?

В идеале я хочу предупреждать во время компиляции и не связывать. Я надеюсь, что ответ не связан с сообщением gcc о том, что я пишу код POSIX, когда считаю, что это противоположность тому, что я хочу сказать. Что я не понимаю?

Ответ 1

  • Вы не получите сообщение об ошибке, извините. Библиотеки так не работают. Функция index является частью стандартной библиотеки. Стандартная библиотека поддерживает одновременно несколько версий C (и POSIX), а макросы выбирают, какие прототипы подвергаются.

  • Флаг -ansi эквивалентен -std=c89, поэтому не делайте этого.

  • Вы правы, что _POSIX_C_SOURCE предоставляет дополнительные функциональные возможности, но также указывает, какую версию функции выставить. Определение _POSIX_C_SOURCE=200112L означает, что index появляется в <strings.h> вместо <string.h>. Он все еще там. Указание POSIX 2008 полностью избавится от index, поскольку оно было удалено из более поздних версий стандарта POSIX.

  • Существует макрос, который означает "только ANSI C", и это _ANSI_SOURCE.

  • Вы можете получить ошибку компиляции (но не ссылку), добавив -Werror-implicit-function-declaration.

$ gcc -Werror-implicit-function-declaration \
    -D_ANSI_SOURCE -pedantic -Wall -std=c99 ...
error: implicit declaration of function 'index'

Это, похоже, отлично работает на всех комбинациях OS X 10.5/10.8, GCC 4.0/4.2.

Ответ 2

Чтобы получить среду C99, передайте флаги -std=c99 -pedantic в gcc. Это не должно определять какие-либо дополнительные макросы для тестирования функций.

Обратите внимание, что это только опускает объявления, потому что они вторгаются в пространство имен, зарезервированное программистом. Фактические символы по-прежнему могут быть доступны - они не должны влиять на компиляцию правильной программы C99, потому что они, как правило, являются "слабыми" символами, но они не будут вызывать ошибку, если вы объявите их сами и используйте их.

Ответ 3

Для записи: с помощью icc я нашел наиболее полезным сделать

icc -no-gcc -diag-enable port-win -fabi-version=2 -std=c99 ...

который пропустит все gcc-специфические voodoo в файлах системных заголовков и предупредит о POSIXisms, которые не существуют в Windows.

Что касается ошибки, я бы просто использовал -Werror.

К сожалению, gcc не может отключить обработку атрибутов gnu в файлах системных заголовков. И, что еще более печально, заявленная версия gcc не поддерживает синтаксис -Werror=<diagnostic>, чтобы бросать ошибки только при определенных предупреждениях.

Итак, по сути, комбинация компилятора и версии, о которой вы говорите, не может действительно помочь вам в том, что вы хотите.