【问题标题】:getchar_unlocked() implicit declaration in C99C99 中的 getchar_unlocked() 隐式声明
【发布时间】:2016-07-07 06:16:40
【问题描述】:

使用getchar_unlocked 并使用--std=c99 标志编译会给出如下警告-

警告:函数“getchar_unlocked”的隐式声明 [-Wimplicit-function-declaration]

如果编译时没有标志,不会给出任何警告。有没有办法解决它?

【问题讨论】:

  • --std=c99 是一种严格模式,您可以考虑改用--std=gnu99。没有精力尝试,但有人可能会:-)
  • @paxdiablo,是的,应该可以,当人们想要使用 C 标准的扩展,即 POSIX 时,不应将编译器限制为裸 C99。更好的是切换到gnu11,无论如何,这似乎是较新的 gcc 版本的默认设置。

标签: c c99


【解决方案1】:

从 C99 开始,在调用函数之前必须有一个可见的函数原型。虽然早期的 C 标准只是愚蠢地假设编译器未知的任何函数都具有int func (params) 格式,这反过来又会在大多数情况下导致严重的错误。

正确声明getchar_unlocked 的原型,该错误就会消失。

请注意,任何标准库中都不存在这样的函数。看来您可能必须包含一些非标准库才能让编译器找到该函数。

【讨论】:

  • 这并不完全正确。函数原型类型存在于 stdio.h 但在 ['bare'] ansii C 中不可见。由于该函数来自 posix 定义,因此必须在源代码中具有以下 #defined 之一:POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE || _BSD_SOURCE || _SVID_SOURCE --或者-- 选择一个 gcc 选项 -std=xxx 包括像 -std=gnu99 这样的 posix 函数
【解决方案2】:

_unlocked 版本的get... 函数是 POSIX 扩展。它们不是 C99 标准功能的一部分。 get... 函数的完整列表在 7.19.1.5 中给出:getwcgetwchargetcgetchargets(已弃用)。

当函数不在此列表中时,符合 C99 的编译器必须警告您,您的程序可能无法与其他符合 C99 的编译器一起编译。

【讨论】:

  • 相反,不允许符合标准的编译器在标准库头文件中随意转储任何非标准废话。他们必须关注naming conventions,他们不能给一个函数起一个像getchar_unlocked 这样的名字并把它放在stdio.h 中。显然,标准 C 和功能失调的 POSIX 标准之间的又一次冲突。
  • @Lundin,为什么会有冲突? POSIX 扩展了 C 标准,仅此而已,它说得很清楚。要使用它,你必须告诉编译器你想要它。 -std=c99 恰恰相反,你想要纯 C99 并且没有扩展。
  • @JensGustedt POSIX 应该是操作系统 API 的标准。它不应该担心干预编程语言的标准。它没有理由调用非标准行为。它也可以像任何其他 3rd 方库一样与 C 和平共存,但是不,那太聪明了……这一切都归结为 C 和 Unix 从一开始就相互纠缠在一起,而 POSIX 起源于来自 *nix。他们没有制定适用于任何操作系统的标准,而是制定了一个标准,声明“像在 Unix 中那样做”。
【解决方案3】:

-ansi-std=c99 等方言选择选项会导致编译器定义某些宏(除了改变接受的方言)。

库头文件会对这些宏做出反应。

确切地说,它们的反应方式完全取决于系统(编译器不提供 C 库),但您可以广泛预期的常见行为是,如果您单独使用这些标志之一(没有任何其他“功能选择宏"),它的作用是隐藏不在指定 ISO C 方言中的函数、宏和其他全局符号的声明。

ISO C 对getchar_unlocked 一无所知。 <stdio.h>(通常是 ISO C 标头)中存在这样的声明是 POSIX 扩展,它基本上是不合格的,因为 getchar_unlocked 是严格符合 C 程序可以使用的标识符,即使它们包含 <stdio.h>。当您使用 -ansi-std=c99 时,<stdio.h> 标头会侦听并将其自身鞭打成符合 ISO-C 的形状,从而隐藏此类扩展。

在表现良好的 POSIX 系统上,您可以要求您需要一种 ISO C 方言您希望某些基本的 1990 年式 POSIX 功能在头文件中可见,例如:

gcc -std=c99 -D_POSIX_SOURCE ...
               ^^^^^ "feature selection macro"

这些特征选择宏是一门完整的科学,对于这个问题和答案来说太宽泛了;它们中的某些形式具有值,例如-D_XOPEN_SOURCE=500_POSIX_SOURCE 不需要参数;它是否刚刚定义,但_POSIX_C_SOURCE 是数字。

我刚刚检查了 glibc 和 Cygwin:在两者上,_POSIX_SOURCE 足以显示 getchar_unlocked 声明。它相当古老,可以追溯到 POSIX.1 1996。

注意:在某些系统上,多个特征选择宏不能合理地发挥作用;它们给你一个集合的交集而不是联合,所以-D_POSIX_SOURCE-D_BSD_SOURCE 一起最终意味着“只向我声明那些特定于经典 BSD 的少数函数,这些函数也已经在 POSIX 中标准化”,这意味着几乎没有声明任何内容。

【讨论】:

    【解决方案4】:

    getchar_unlocked 不是 C 标准函数。

    编译它强制 c99 标准本身不支持它。

    【讨论】:

      猜你喜欢
      • 2011-10-05
      • 2012-02-28
      • 2012-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-28
      • 2018-10-10
      • 1970-01-01
      相关资源
      最近更新 更多