使用 gcc,严格包含 C99 符号,特别排除 POSIX

问题描述 投票:0回答:3

经过多年编程,我正在学习 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

函数
c macos gcc linker
3个回答
12
投票
标准库的一部分。 标准库同时支持多个版本的 C(和 POSIX),并且宏选择公开哪些原型。
  1. -ansi标志相当于-std=c89

    ,所以停止这样做。
  2. 您说得对,
    _POSIX_C_SOURCE
    公开了附加功能,但它还指定了要公开的功能的
    哪个版本

    。 定义
  3. _POSIX_C_SOURCE=200112L
  4. 意味着

    index

    出现在
    <strings.h>中而不是<string.h>
    中。  它还在那里。  指定 2008 POSIX 将完全消除 
    index
    ,因为它已从更高版本的 POSIX 标准中删除。
    is
    一个宏,意思是“仅限ANSI C”,那就是
    _ANSI_SOURCE

  5. 添加 -Werror-implicit-function-declaration

     可能会出现编译错误(但不是链接错误)。

  6. $ gcc -Werror-隐式函数声明 \ -D_ANSI_SOURCE -迂腐 -Wall -std=c99 ... 错误:函数“index”的隐式声明

    这似乎在 OS X 10.5/10.8、GCC 4.0/4.2 的所有组合上都能正常工作。

要获得 C99 环境,请将标志
-std=c99 -pedantic
传递给 gcc。 这不应该定义任何额外的功能测试宏。

但请注意,这只是省略了

1
投票
,因为它们侵入了 C99 程序员保留的命名空间。 实际的符号仍然可能可用 - 这些不应该影响正确的 C99 程序的编译,因为它们往往是“弱”符号,但如果您自己声明并使用它们,它们不会强制出现错误。


郑重声明:使用

icc

我发现这样做最有帮助

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

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


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


不幸的是,gcc 无法关闭系统头文件中 gnu 特定的属性处理。 而且,更不幸的是,指定的 gcc 版本不支持

-Werror=<diagnostic>

语法,仅在某些警告时抛出错误。

所以本质上,你所说的编译器和版本的组合并不能真正帮助你实现你想要的。

© www.soinside.com 2019 - 2024. All rights reserved.