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

时间:2012-08-13 07:51:45

标签: c macos gcc compiler-construction linker

经过多年的编程,我正在修课。我的教练没有使用POSIX机器,最近我因在作业中使用index功能而受到惩罚。我做了一些研究,我注意到虽然index是AT& T Unix的早期部分并且符合POSIX标准,但它不是C99标准的一部分。 我希望gcc帮助我找到类似符号的使用。我正在使用gcc 4.2( not 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’

这让我感到困惑,我想让程序也无法链接。它让我困惑的原因是,我读到at opengroup.org定义该宏应公开 POSIX符号,而不是隐藏它们。所以这是我的问题,简洁的形式:

如何制作gcc 4.2(在OSX 10.6上)在严格 C99的环境中编译和链接我的程序没有其他符号?< /强>

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

3 个答案:

答案 0 :(得分:11)

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

  2. -ansi标志相当于-std=c89,所以请停止这样做。

  3. 你是对的_POSIX_C_SOURCE公开了其他功能,但它也指定了要公开的功能的哪个版本。定义_POSIX_C_SOURCE=200112L表示index而不是<strings.h>中显示<string.h>。它还在那里。指定2008 POSIX将完全摆脱index,因为它已从更高版本的POSIX标准中删除。

  4. 一个宏,意思是“只有ANSI C”,即_ANSI_SOURCE

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

  6. $ 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>语法仅在某些警告时抛出错误。

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