【问题标题】:Can Clang warn me when I use non-standard functions provided by the GNU C Library?当我使用 GNU C 库提供的非标准函数时,Clang 可以警告我吗?
【发布时间】:2014-05-24 19:08:21
【问题描述】:

我正在 OS X 上编写一个 C 程序并用 clang 编译它。我对 C 语言很陌生,我开始明白像 getline() 这样的一些函数很有用但不是标准的。我希望能够在没有 GNU C 库的系统上编译程序。不确切知道哪些功能是非标准的,我希望有一个命令行开关让 clang 在我使用这些功能时向我发出警告。有吗?

clang --version 的输出:

Apple LLVM 版本 5.1 (clang-503.0.40)

【问题讨论】:

  • getline 是标准的; OSX 已经过时了。
  • @R.. 它仍然无法在非 POSIX 兼容的系统上运行。
  • @michielvoo getline() 是 POSIX.1 2008 的一部分。
  • @R.. 不实施 POSIX.1 2008 并不是“严重过时”。在稳定性比花哨的新功能更重要的工业软件中,事情的进展会慢一些。

标签: c clang


【解决方案1】:

您可以使用feature test macros(另请参阅:XSH 2.2.1 POSIX.1 Symbols)请求仅查看一组特定的标准接口。特别是,

-D_XOPEN_SOURCE=600

在命令行上或

#define _XOPEN_SOURCE 600

应该为过时的 2001 版本的 POSIX(最新的 OSX 支持)公开 POSIX 基础和 XSI 选项。如果您只想要基础,没有 XSI,请将 _POSIX_C_SOURCE 定义为 200112L

【讨论】:

  • 谢谢,这在clang中有效。它打印“警告:函数'getline'的隐式声明在C99 [-Wimplicit-function-declaration]中无效”
  • 另外添加-Werror=implicit-function-declaration。隐式函数不是有效的 C 语言并且总是一个严重的编程错误。
  • @R.. 它们是有效的 C89,但不是有效的 C99。如果 OP 使用-std=c99 编译或以c99 调用编译器,他应该得到一个错误。尽管如此,POSIX 包含的语言(可以追溯到 POSIX 强制使用 C89 时)为标准函数提供自己的原型或在没有原型的情况下调用它们是未定义的行为。
  • @FUZxxl:我认为你是基于过时或记忆错误的信息。 POSIX 明确指出,您可以为任何标准函数提供您自己的原型,只要它们不需要其标头中的类型。在没有声明的情况下调用(注意:这与没有原型不同)始终是编译必须诊断的约束违规,而不仅仅是 UB。
【解决方案2】:

没有命令行开关可以说“告诉我这是否不标准”。开发需要跨各种平台兼容的代码的最常见方法是gnu autotools suite,它为您提供了一个配置脚本,用于检查各种功能并允许您围绕它进行编码,或者让系统在开始之前放弃进一步。

【讨论】:

  • 是的,有。请参阅功能测试宏和我的答案。
【解决方案3】:

您可以定义一个特征测试宏,例如_POSIX_C_SOURCE。当存在_POSIX_C_SOURCE 并且没有定义实现定义的功能测试宏(如_BSD_SOURCE_GNU_SOURCE)时,需要符合要求的实现来隐藏任何扩展(即额外的库函数):

#define _POSIX_C_SOURCE 200809L

如果您尝试使用扩展并且定义了此宏,您将收到警告(ANSI 模式)或错误 (C99) 模式,因为该函数的原型不存在。

对于 Mac OS X,不支持 POSIX.1 2008。因此,您必须像这样定义宏以获得 POSIX.1 2001 支持:

#define _POSIX_C_SOURCE 200112L

请注意,在 POSIX.1 2008 中删除了几个函数,但这无关紧要,因为这些函数通常(读取:始终)存在于目标系统上,因为它可能也支持 POSIX.1 2001。

【讨论】:

  • @R.. 添加了关于 OS X 的语言。
【解决方案4】:

没有,主要是因为我知道的几乎所有项目通常都会区分:

  • 编译器
  • 标准库
  • ABI 库

通常这三件事被分开到不同的项目中,并且它们被设计成不会相互影响。有时甚至对此有更分散的看法,编译器被拆分为后端、前端和多个其他模块化项目和插件,就像在带有 clang 的大型 llvm 项目中发生的那样。

正如 Petesh 已经建议的那样,您最好的选择是一些具有这种能力的构建系统,您可以在其中编写构建过程的行为脚本并检测宏是否失败,或者目标系统是否提供 X 功能.

我的建议是cmake 和它自己的wiki,尤其是对于初学者。

【讨论】:

    猜你喜欢
    • 2015-01-07
    • 2013-01-01
    • 2014-06-30
    • 2017-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多