使用gcc,严格包含C99符号,特别是不包括POSIX
经过多年的编程,我正在修课。 我的导师没有使用POSIX机器,最近我因在作业中使用index
function而受到惩罚。 我做了一些研究,我注意到虽然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代码,当我相信这与我想说的相反时。 我不明白的是什么?
-
抱歉,你不会收到链接错误。 图书馆不这样做。
index
函数是标准库的一部分。 标准库同时支持多个版本的C(和POSIX),宏选择暴露哪些原型。 -
-ansi
标志等同于-std=c89
,所以停止这样做。 -
你是对的
_POSIX_C_SOURCE
公开了其他function,但它也指定了要公开的function版本 。 定义_POSIX_C_SOURCE=200112L
意味着index
出现在
而不是
。 它还在那里。 指定2008 POSIX将完全摆脱index
,因为它已从更高版本的POSIX标准中删除。 -
有一个宏意味着“只有ANSI C”,那就是
_ANSI_SOURCE
。 -
您可以通过添加
-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=
语法,仅在某些警告时抛出错误。
所以从本质上讲,你声明的编译器和版本的组合并不能真正帮助你实现你想要的东西。