我只在半小时前才了解到defining a function with a blank argument list is not the same as defining a function with void
as the argument list。这种误解对我来说似乎很常见,我很惊讶,即使我通过了-Wall -Wextra -pedantic
,gcc
和clang
都没有发出任何警告。为什么是这样?默认情况下,为什么不打开-Wstrict-prototypes?
回答
-Wall
其实只是个开始,而-Wextra
还没有到目前为止的路程。
与其引用斯托曼先生的话,为了避免评论他的一些更可疑的观点(比如托马斯迪基提到的观点),我宁愿引用the current GCC manuals,强调我的:
-Wall
- 这使得关于某些用户认为有问题,很容易避免(或修改来禁止警告)结构,并且警告,即使是与宏一起。
-Wextra
- 这使一些额外的警告标志不是由-Wall启用。
所以,如果你说“全部,再加上”,你实际上是在说“简单的,再加上一些”。更好地检查该手册。
我当然会认为函数定义中的未指定参数是一个_questionable构造。事实上,我这样定义函数的唯一原因是因为我认为它是在参数列表中用'void'定义它们的_same_。使用未指定参数定义的简单'warning:函数(或者甚至是当前的'-Wstrict-prototypes'消息)将指向我(和其他许多人,我敢肯定)正确的方向。一旦你知道了,你一定很容易避免 - 你也可以让你的编辑为你做集体工作。 –
@BlacklightShining:这里的信息是,a)*总是以最严格的错误检查模式运行编译器*,b)'-Wall -Wextra'不是。 ;-) – DevSolar
Downvoted“没用”没有评论为什么。 SO的祸根再次袭来。 – DevSolar
其中一个原因可能是Richard Stallman的个人品味,他是gcc的创建者和原始首席开发人员。下面是他的信息,其余上面提到:从-Wall
是不同首先提到
Date: Thu, 2 Sep 1999 23:19:27 -0400
Message-Id: <[email protected]>
From: Richard Stallman <[email protected]>
To: [email protected]
Subject: On using -Wall in GCC
Reply-to: [email protected]
Resent-From: [email protected]
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
选项(尽管存在于GCC 1.42在1992年1月):
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
的更多上下文,有助于阅读整个部分,而不是有选择地挑选文本。在current文档的最后一段为-Wall
例如指出-Wall
是不全面的,并最终纳入的原因是判断的问题(如原始文档中):
注意一些警告标志不由-Wall暗示。其中一些人警告用户通常不认为有问题的建筑,但有时候您可能希望检查;其他人警告在某些情况下必要或难以避免的构造,并且没有简单的方法来修改代码来抑制警告。其中一些由-Wextra启用,但其中许多必须单独启用。
至于那个其判断 - 这将是海湾合作委员会的原始开发商1990年左右
有很多的遗留代码在那里(从之前的空隙),它会抛出误导性的警告。随着时间的推移,新代码与旧代码的比例发生变化,这些警告变得更有用。
并非如此(自1989年以来,“空白”就是标准)。 –
我改变了我的想法;-)。 –
- 1. 默认情况下,为什么不打包结构?
- 2. 默认情况下打开地图
- 3. 默认情况下,为什么不安装glibc?
- 4. 为什么Map在默认情况下在Scala中不可变?
- 5. 为什么Multicore JIT不在默认情况下在.net 4.5中?
- 6. 默认情况下,为什么不在Windows上安装Python?
- 7. 默认情况下为什么不应用(RankNTypes使用)?
- 8. 为什么默认情况下不启用物理Web?
- 9. 默认情况下,为什么scons看不到〜/ .scons/site_scons?
- 10. CKEDITOR - 默认情况下打开粘贴为纯文本窗口
- 11. 产量和默认情况||不输出默认情况下
- 12. 默认情况下不会打开团队资源管理器
- 13. 默认情况下不要打开导航抽屉
- 14. 在不打开默认站点的情况下启动IIS Express
- 15. 为什么默认情况下我的gradle下载源?
- 16. 为什么默认情况下,varibale在c中声明为static?
- 17. 默认情况下,为什么AutoDetectChangesEnabled设置为false?
- 18. 下拉菜单在默认情况下打开php
- 19. 开放的系统,默认情况下
- 20. 为什么不在没有Application.Run()的情况下打开winform?
- 21. 默认情况下修改默认命令:默认命令为
- 22. 默认情况下,为什么git会在合并后提交?
- 23. System.Drawing和System.EnterpriseServices为什么在默认情况下asp.net mvc 2
- 24. 默认情况下,为什么Grails会忽略HTTP Accept头?
- 25. Java:为什么有人会在默认情况下编写super()?
- 26. 默认情况下,为什么在sqlite中禁用约束?
- 27. swiftmailer为什么在默认情况下与symfony2一起发货?
- 28. 默认情况下,为什么清漆sess_timeout很低?
- 29. 为什么PreAuthenticate在默认情况下未启用?
- 30. 为什么红色边框默认情况下,在形式
不久之前,Richard Stallman向邮件列表发送了一条消息,解释其他人发现警告有用,但他没有。可能对默认值有一定影响。 –
应该提醒Richard Stallman编译器会被很多不自动编写正确代码的人使用。但是,没有启用该编译器开关允许程序在没有原型的情况下编写具有定义的函数的代码,只要该函数在被调用之前声明为 – user3629249
这是向后兼容性问题。在旧C中,当函数以空参数列表呈现给编译器时,这意味着它是未定义的参数列表,编译器假定您没有指定参数的数量和类型。为了节省这一点,并为了符合检查参数的ANSI-C要求,选择了“void”关键字。 –