经过多年的编程,我正在修课。我的教练没有使用POSIX机器,最近我因在作业中使用index
功能而受到惩罚。我做了一些研究,我注意到虽然index
是AT& T Unix的早期部分并且符合POSIX标准,但它不是C99标准的一部分。 我希望gcc帮助我找到类似符号的使用。我正在使用gcc 4.2( not 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’
这让我感到困惑,和我想让程序也无法链接。它让我困惑的原因是,我读到at opengroup.org定义该宏应公开 POSIX符号,而不是隐藏它们。所以这是我的问题,简洁的形式:
如何制作gcc 4.2(在OSX 10.6上)在严格 C99的环境中编译和链接我的程序没有其他符号?< /强>
理想情况下,我希望在编译期间发出警告并且无法链接。我希望答案不涉及告诉gcc我我编写POSIX代码,当我认为这与我想说的相反时。我不理解的是什么?
答案 0 :(得分:11)
抱歉,您不会收到链接错误。图书馆不这样做。 index
函数是标准库的一部分。标准库同时支持多个版本的C(和POSIX),并且宏选择暴露哪些原型。
-ansi
标志相当于-std=c89
,所以请停止这样做。
你是对的_POSIX_C_SOURCE
公开了其他功能,但它也指定了要公开的功能的哪个版本。定义_POSIX_C_SOURCE=200112L
表示index
而不是<strings.h>
中显示<string.h>
。它还在那里。指定2008 POSIX将完全摆脱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的所有组合。
答案 1 :(得分:1)
要获取C99环境,请将标记-std=c99 -pedantic
传递给gcc。这不应该定义任何其他功能测试宏。
但是请注意,这只省略了声明,因为它们会侵入C99程序员保留的命名空间。实际的符号仍然可能可用 - 这些符号不应该影响正确的C99程序的编译,因为它们往往是“弱”符号,但如果你自己声明并使用它们,它们不会强制错误。< / p>
答案 2 :(得分:1)
对于记录: icc
我发现它最有帮助
icc -no-gcc -diag-enable port-win -fabi-version=2 -std=c99 ...
将跳过系统头文件中所有gcc特定的voodoo,并警告Windows上不存在的POSIXisms。
至于抛出错误,我只使用-Werror
。
不幸的是,gcc无法关闭系统头文件中特定于gnu的属性处理。而且,更不幸的是,声明的gcc版本不支持-Werror=<diagnostic>
语法仅在某些警告时抛出错误。
所以从本质上讲,你声明的编译器和版本的组合并不能真正帮助你实现你想要的东西。