经过多年编程,我正在学习 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 代码,而我相信这与我想要告诉它的相反。我不明白什么?
抱歉,您不会收到链接错误。 图书馆不是这样工作的。 index
-ansi
标志相当于-std=c89
,所以停止这样做。您说得对,
_POSIX_C_SOURCE
公开了附加功能,但它还指定了要公开的功能的哪个版本。 定义
_POSIX_C_SOURCE=200112L
index
出现在
<strings.h>
中而不是<string.h>
中。 它还在那里。 指定 2008 POSIX 将完全消除
index
,因为它已从更高版本的 POSIX 标准中删除。
有is
一个宏,意思是“仅限ANSI C”,那就是
_ANSI_SOURCE
。添加 -Werror-implicit-function-declaration
可能会出现编译错误(但不是链接错误)。
这似乎在 OS X 10.5/10.8、GCC 4.0/4.2 的所有组合上都能正常工作。
-std=c99 -pedantic
传递给 gcc。 这不应该定义任何额外的功能测试宏。但请注意,这只是省略了
郑重声明:使用
icc
icc -no-gcc -diag-enable port-win -fabi-version=2 -std=c99 ...
这将跳过系统头文件中所有 gcc 特定的 voodoo 并警告 Windows 上不存在的 POSIXisms。
至于抛出错误,我只会使用
-Werror
。不幸的是,gcc 无法关闭系统头文件中 gnu 特定的属性处理。 而且,更不幸的是,指定的 gcc 版本不支持
-Werror=<diagnostic>
所以本质上,你所说的编译器和版本的组合并不能真正帮助你实现你想要的。