【问题标题】:Why isn't -Wstrict-prototypes on by default?为什么 -Wstrict-prototypes 默认不启用?
【发布时间】:2015-06-22 05:05:02
【问题描述】:

我了解到,使用空白参数列表定义函数与使用 void 作为参数列表定义函数不同。请参阅 (Is it better to use C void arguments "void foo(void)" or not "void foo()"?)。

这种误解对我来说似乎很常见,我很惊讶gcc 和clang 都没有发出任何警告,即使我通过了-Wall -Wextra -pedantic。

这是为什么?

【问题讨论】:

  • 不久前,Richard Stallman 向邮件列表发送了一条消息,解释说其他人发现警告有用,但他没有。可能这对默认值有一些影响。
  • 应该提醒 Richard Stallman,编译器将被许多不会“自动”编写正确代码的人使用。但是,如果不启用该编译器开关,则程序可以编写没有原型定义的函数的代码,只要在函数被调用之前就声明了函数
  • 这是一个向后兼容性问题。在旧 C 语言中,当一个函数以空参数列表呈现给编译器时,这意味着它是未定义的参数列表,编译器假设您没有指定参数的数量和类型。为了保存这一点,并与检查参数的 ANSI-C 要求保持一致,选择了 void 关键字。

标签: gcc clang compiler-warnings


【解决方案1】:

-Wall 实际上只是开始,-Wextra 远不是路的尽头。

与其引用 Stallman 先生的话,而且不得不重重地咬住我的舌头以避免评论他的一些更有问题的观点(比如 Thomas Dickey 提到的那个),我宁愿引用 the current GCC manuals,强调我的:

-Wall -- 这会启用所有警告关于一些用户认为有问题的构造,以及易于避免(或修改以防止警告),甚至与宏一起使用。

-Wextra -- 这会启用 一些额外的警告标志,而这些 -Wall 没有启用。

所以,如果你说“全部,加上额外”,你实际上是在说“简单的,加上一些”。最好查看该手册以了解更多信息。

【讨论】:

  • 我当然会认为函数定义中未指定的参数是一个有问题的构造。 事实上,我以这种方式定义函数的唯一原因是因为我认为它是 与在参数列表中使用void 定义它们相同。一个简单的warning: function defined with unspecified arguments(甚至是当前的-Wstrict-prototypes 消息)会为我(以及其他许多人,我敢肯定)指明正确的方向。一旦你知道知道,这当然很容易避免——你也可以让你的编辑为你做这件事。
  • @BlacklightShining:这里的信息是,a) 始终以尽可能严格的错误检查模式运行编译器,b) -Wall -Wextra 不是这样。 ;-)
【解决方案2】:

其中一个原因可能是 gcc 的创建者和原始首席开发者 Richard Stallman 的个人品味。这是我上面提到的他的信息:

Date: Thu, 2 Sep 1999 23:19:27 -0400
Message-Id: <gnusenet199909030319.XAA08701@psilocin.gnu.org>
From: Richard Stallman <rms@gnu.org>
To: gnu-prog@gnu.org
Subject: On using -Wall in GCC
Reply-to: rms@gnu.org
Resent-From: info-gnu-prog-request@gnu.org

Status: RO
Content-Length: 841
Lines: 17

I'd like to remind all GNU developers that the GNU Project
does not urge or recommend using the GCC -Wall option.

When I implemented the -Wall option, I implemented every warning that
anyone asked for (if it was possible).  I implemented warnings that
seemed useful, and warnings that seemed silly, deliberately without
judging them, to produce a feature which is at the upper limit of 
strictness.

If you want such strict criteria for your programs, then -Wall is for
you.  But changing code to avoid them is a lot of work.  If you don't
feel inclined to do that work, please don't let anyone else pressure
you into using -Wall.  If people say they would like to use it, you
don't have to listen.  They're asking you to do a lot of work.
If you don't feel it is useful, you don't have to do it.

I never use -Wall myself.

在gcc-2.7.2.3 的ChangeLog.4 文件中,-Wstrict-prototypes 选项(尽管在 1992 年 1 月出现在 gcc 1.42 中)被首次提到与 -Wall 不同:

Thu Nov 21 15:34:27 1991  Michael Meissner  (meissner at osf.org)

        * gcc.texinfo (warning options): Make the documentation agree with
        the code, -Wstrict-prototypes and -Wmissing-prototypes are not
        turned on via -Wall; -Wnoparenthesis is now spelled
        -Wno-parenthesis.
        (option header): Mention that -W options take the no- prefix as well
        as -f options.

此外,在文档 (gcc.info-3) 中,它出现在本段开头的部分:

   The remaining `-W...' options are not implied by `-Wall' because
they warn about constructions that we consider reasonable to use, on
occasion, in clean programs.

选项本身是这样记录的:

`-Wstrict-prototypes'
     Warn if a function is declared or defined without specifying the
     argument types.  (An old-style function definition is permitted
     without a warning if preceded by a declaration which specifies the
     argument types.)

考虑到上下文,将选项分开的原因很容易理解:这仅在 C 标准化几年后,很少有程序转换为 ANSI C。gcc 有其他选项可以帮助解决这个问题,例如,-Wtraditional。

复杂工具的开发者必须牢记兼容性。在类别之间移动选项保证会破坏某些人的构建脚本。比如gcc也有

`-Werror'
     Make all warnings into errors.

有些人经常使用。不必要地打开开发人员之前选择不使用的警告并因此停止编译不是保持兼容性的方法。

有关-Wall 与-Wstrict-prototypes 的更多上下文,阅读整个 部分而不是选择性地挑选文本会有所帮助。例如,-Wall 的 current 文档的最后一段指出 -Wall 并不全面,最终包含的原因是一个判断问题(如原始文档中所示):

请注意,-Wall 并不暗示某些警告标志。其中一些警告用户通常不认为有问题但偶尔您可能希望检查的结构;其他人警告在某些情况下必须或难以避免的构造,并且没有简单的方法来修改代码以抑制警告。其中一些由 -Wextra 启用,但其中许多必须单独启用。

至于 的判断是——应该是 1990 年左右 gcc 的原始开发者。

【讨论】:

  • 没有帮助,因为它既没有提供好的建议,也没有反映-Wall的当前含义。
  • 基于该邮件,您还可以提出以下论点: 1. RMS 不会影响 GCC 开发人员为 -Wall 设置的默认值,因为他甚至不使用该标志。 2. 没有人要求将 -Wstrict-prototypes 添加到默认值中,因为 RMS 说他包含了人们要求的所有内容。虽然这也没有真正回答任何问题。
  • 虽然从技术上讲这不是一个答案,而只是一个引用,但如果一个人使用了几个脑细胞,它就是一个引用。在评论中提供这些信息在技术上也是不可能的,所以别傻了,伙计们。
  • @PeterSchneider:关键是无论 Stallman 先生认为他如何实现 -Wall,它都与 -Wall 今天的含义无关,或者对是否包含 -Wstrict-prototypes 有任何影响在它与否。简直是OT。
  • 有比无知更糟糕的事情(例如,断章取义)。
【解决方案3】:

那里有很多遗留代码(在 void 之前),它们会引发误导性警告。随着时间的推移,新代码与旧代码的比例会发生变化,因此这些警告会变得更加有用。

【讨论】:

  • 没有那么多(void 是自 1989 年以来的标准)。
  • 我把 i 改成了 ;-)。
【解决方案4】:

因为非常多的程序员使用空参数列表来表示没有参数,并且所有这些程序员都会被阻止使用包含它的警告集。使用 (void) 在从/到 C 到/从另一种编程语言转换时也会导致问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-25
    • 2010-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多