С 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>
, чтобы бросать ошибки только при определенных предупреждениях.
Итак, по сути, комбинация компилятора и версии, о которой вы говорите, не может действительно помочь вам в том, что вы хотите.