使用gcc,严格包含C99符号,特别是不包括POSIX

经过多年的编程,我正在修课。 我的导师没有使用POSIX机器,最近我因在作业中使用indexfunction而受到惩罚。 我做了一些研究,我注意到虽然index是AT&T Unix的早期部分,并且符合POSIX标准,但它不是C99标准的一部分。 我希望gcc帮我找到类似符号的用法 。 我正在使用gcc 4.2( 不是 llvm)在OSX上编译

我的第一站研究涉及注意我的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符号,而不是隐藏它们。 所以这是我的问题以简洁的forms:

如何制作gcc 4.2(在OSX 10.6上)在一个严格的 C99环境中编译和链接我的程序, 没有其他符号可用?

理想情况下,我希望在编译期间发出警告并且无法链接 。 我希望答案不涉及告诉gcc我正在编写POSIX代码,当我相信这与我想说的相反时。 我不明白的是什么?

  1. 抱歉,你不会收到链接错误。 图书馆不这样做。 index函数标准库的一部分。 标准库同时支持多个版本的C(和POSIX),宏选择暴露哪些原型。

  2. -ansi标志等同于-std=c89 ,所以停止这样做。

  3. 你是对的_POSIX_C_SOURCE公开了其他function,但它也指定了要公开的function版本 。 定义_POSIX_C_SOURCE=200112L意味着index出现在而不是 。 它还在那里。 指定2008 POSIX将完全摆脱index ,因为它已从更高版本的POSIX标准中删除。

  4. 有一个宏意味着“只有ANSI C”,那就是_ANSI_SOURCE

  5. 您可以通过添加-Werror-implicit-function-declaration来获取编译错误(但不是链接错误)。

 $ gcc -Werror-implicit-function-declaration \
     -D_ANSI_SOURCE -pedantic -Wall -std = c99 ...
错误:函数'index'的隐式声明

这似乎适用于OS X 10.5 / 10.8,GCC 4.0 / 4.2的所有组合。

要获得C99环境,请将标志-std=c99 -pedantic给gcc。 这不应该定义任何其他function测试宏。

但请注意,这只是省略了声明 ,因为它们会侵入C99程序员保留的命名空间。 实际的符号仍然可能可用 – 这些符号不应该影响正确的C99程序的编译,因为它们往往是“弱”符号,但如果你自己声明并使用它们,它们不会强制出错。

为了记录:使用icc我发现它最有帮助

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

这将跳过系统头文件中所有gcc特定的voodoo,并警告Windows上不存在的POSIXisms。

至于抛出错误,我只使用-Werror

不幸的是,gcc无法关闭系统头文件中特定于gnu的属性处理。 而且,更不幸的是,声明的gcc版本不支持-Werror=语法,仅在某些警告时抛出错误。

所以从本质上讲,你声明的编译器和版本的组合并不能真正帮助你实现你想要的东西。