遵守标准有多重要?
对于像 C++ 这样的语言来说,标准的存在是必须的。好的编译器会尽最大努力(至少是大多数好的编译器)来遵守。许多编译器都有语言扩展,其中一些是标准允许的,有些则不允许。后一种例子有 2 个:
gcc 的 typeof
微软的编译器允许纯虚函数声明同时具有纯说明符 (=0) 和定义(标准禁止这样做) - 我们不讨论为什么,那是另一个话题了:)
(还有许多其他示例)
这两个示例在以下意义上都很有用:example1 是一个非常有用的功能,它将在 c++0x 中以不同的名称提供。 example2 也很有用,微软已决定不遵守毫无意义的禁令。
我很感激编译器提供了语言扩展来帮助我们开发人员完成日常工作。但这里有一个问题:难道不应该有一个选项,在设置时要求编译器尽可能符合标准,无论它们是否同意标准。例如,Visual Studio有这样一个选项,称为禁用语言扩展。但是,嘿,他们仍然允许 example2。
我希望大家能够正确理解我的问题。 MSVC 允许 example2 是一件很棒的事情,我非常希望该功能能够出现在标准中。它不会破坏任何兼容的代码,也不会做任何坏事。这只是不标准。
当禁用语言扩展设置为 true 时,您希望 Microsoft 禁用 example2 吗?请注意,microsoft、example2 等词是占位符:) 为什么?
再次强调,只是为了确定一下。关键点是:当编译器提供一个非标准的更好的替代方案时,编译器是否应该为某个功能提供一个兼容的版本(可以在设置中设置)(在其限制内,例如我不是在谈论导出)。甚至可能是标准的超集,因此不会破坏任何东西。
For a language like C++ the existence of a standard is a must. And good compilers try their best (well, most of the good compilers, at least) to comply. Many compilers have language extensions, some of which are allowed by the standard, some of which are not. Of the latter kind 2 examples:
gcc's typeof
microsoft's compilers allow a pure virtual function declaration to have both a pure-specifier(=0) and a definition (which is prohibited by the standard - let's not discuss why, that's another topic:)
(there are many other examples)
Both examples are useful in the following sense: example1 is a very useful feature which will be available in c++0x under a different name. example2 is also useful, and microsoft has decided not to respect the ban that made no sense.
And I am grateful that compilers provide language extensions that help us developers in our routine. But here's a question: shouldn't there be an option which, when set, mandates that the compiler be as standards compliant as it can, no matter whether they agree with the standard or not. For example visual studio has such an option, which is called disable language extensions. But hey, they still allow example2.
I want everyone to understand my question correctly. It is a GREAT thing that MSVC allows example2, and I would very much like that feature to be in the standard. It doesn't break any compliant code, it does nothing bad. It just isn't standard.
Would you like that microsoft disable example2 when disable language extensions is set to true? Note that the words microsoft, example2, etc. are placeholders :)
Why?
Again, just to make sure. The crucial point is: Should a compiler bother to provide a compliant version (optionally set in the settings)(in its limits, e.g. I am not talking about export) for a certain feature when they provide a better alternative that is not standard and is perhaps even a superset of the standard, thus not breaking anything.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
标准合规性很重要,其根本原因是它使您的代码更易于维护。这体现在多种方面:
从一个版本的编译器移植到另一个版本。我曾经不得不发布一个从 VC6 到 VC9 的 120 万个 LOC 应用程序。 VC6 因严重不合规而臭名昭著,即使它是新的。即使在新编译器以最低警告级别拒绝的最高警告级别上,它也允许不合规的代码。如果代码一开始就以更合规的方式编写,那么这个项目就不会(不应该)花费 3 个月的时间。
从一个平台移植到另一个平台。正如你所说,当前的 MS 编译器具有语言扩展。其中一些由其他平台上的编译器共享,有些则不然。即使它们是共享的,行为也可能略有不同。编写兼容的代码,而不是使用这些扩展,可以使您的代码从一开始就是正确的。 “移植”变得简单地把树拉下来并进行重建,而不是挖掘应用程序的内部试图找出为什么 3 位是错误的。
C++ 由标准定义。编译器使用的扩展改变了语言。如果您使用标准 C++ 而不是您的编译器支持的方言,那么了解 C++ 但不了解您的编译器使用的方言的新上线程序员将更快地掌握速度。
Standards compliance is important for the fundamental reason that it makes your code easier to maintain. This manifests in a number of ways:
Porting from one version of a compiler to another. I once had to post a 1.2 million-LOC app from VC6 to VC9. VC6 was notorious for being horribly non-Compliant, even when it was new. It allowed non-compliant code even on the highest warning levels that the new compiler rejected at the lowest. If the code had been written in a more compliant way in the first place, this project wouldn't (shouldn't)have taken 3 months.
Porting from one platform to another. As you say, the current MS compilers have language extensions. Some of these are shared by compilers on other platforms, some are not. Even if they are shared, the behavior may be subtly different. Writing compliant code, rather that using these extensions, makes your code correct from the word go. "Porting" becomes simply pulling the tree down and doing a rebuild, rather than digging through the bowels of your app trying to figure out why 3 bits are wrong.
C++ is defined by the standard. The extensions used by compilers changes the language. New programmers coming online who know C++ but not the dialect your compiler uses will get up to speed more quickly if you write to Standard C++, rather than the dialect that your compiler supports.
首先回复几条评论。有问题的 MS VC 扩展是这样的:
该标准允许您实现纯虚函数,但不能像这样“就地”,所以您必须这样写:
至于原来的问题,是的,我认为编译器拥有一种尽可能准确地遵循(并强制执行)标准的模式是一个好主意。虽然大多数编译器都有这样的功能,但结果不一定如您/我所希望的那样准确地表示标准。
至少在我看来,这个问题的唯一答案是对于那些关心可移植性的人来说,定期拥有(和使用)至少几个编译器。对于C++,其中之一应该基于EDG前端;我相信它比大多数其他产品具有更好的一致性。如果您定期使用英特尔的编译器,那就没问题。否则,我建议您获取一份 Comeau C++;它只要 50 美元,而且是最接近“参考”的东西。您还可以在线使用 Comeau,但如果您经常使用它,那么值得您自己购买一份。
听起来不像是 EDG 或 Comeau 的托儿之类的东西,但即使您不太关心可移植性,我还是建议您获取一份副本 - 它通常会产生出色的错误消息。多年来,它干净、清晰的错误消息(全部由其本身)节省了足够的时间,足以为编译器支付数倍的费用。
编辑:再看一遍,有些建议看起来相当过时,尤其是对 EDG/Comeau 的建议。自从我最初写这篇文章以来的三年里,Clang 已经从纯粹的实验发展到对于生产使用相当合理。同样,gcc 维护者(IMO)在一致性方面也取得了长足的进步。
与此同时,Comeau 尚未发布其编译器的任何新版本,并且发布了 C++ 标准的新版本。结果,Comeau 现在相对于当前标准来说已经相当过时了(而且情况似乎变得更糟,而不是更好——委员会已经批准了一项新标准的委员会草案,该草案很可能成为 C+) +14)。
因此,尽管我当时推荐了科莫,但今天我(充其量)很难这样做。幸运的是,它提供的大部分优点现在都可以在更主流的编译器中使用——如上所述,Clang 和 gcc 都(显着地)改进了合规性,并且它们的错误消息也得到了显着改进(Clang 已几乎从一开始就非常重视更好的错误消息)。
底线:我仍然建议至少安装两个可用的编译器,但今天我可能会选择与最初编写此答案时不同的编译器。
First, a reply to several comments. The MS VC extension in question is like this:
The standard allows you to implement the pure virtual function, but not "in place" like this, so you have to write it something like this instead:
As to the original question, yes, I think it's a good idea for the compiler to have a mode in which it follows (and enforces) the standard as accurately as possible. While most compilers have that, the result isn't necessarily as accurate a representation of the standard as you/I would like.
At least IMO, about the only answer to this is for people who care about portability to have (and use) at least a couple of compilers on a regular basis. For C++, one of those should be based on the EDG front-end; I believe it has substantially better conformance than most of the others. If you're using Intel's compiler on a regular basis anyway, that's fine. Otherwise, I'd recommend getting a copy of Comeau C++; it's only $50, and it's the closest thing to a "reference" available. You can also use Comeau online, but if you use it on a regular basis, it's worth getting a copy of your own.
Not to sound like an EDG or Comeau shill or anything, but even if you don't care much about portability, I'd recommend getting a copy anyway -- it generally produces excellent error messages. Its clean, clear error messages (all by themselves) have saved enough time over the years to pay for the compiler several times over.
Edit: Looking at this again, some of the advice is looking pretty dated, especially the recommendation for EDG/Comeau. In the three years since I originally wrote this, Clang has progressed from purely experimental to being quite reasonable for production use. Likewise, the gcc maintainers have (IMO) made great strides in conformance as well.
During the same time, Comeau hasn't released a single new version of their compiler, and there's been a new release of the C++ standard. As a result, Comeau is now fairly out of date with respect to the current standard (and the situation seems to be getting worse, not better -- the committee has already approved a committee draft of a new standard that is likely to become C++14).
As such, although I recommended Comeau at that time, I'd have difficulty (at best) doing so today. Fortunately, most of the advantages it provided are now available in more mainstream compilers -- both Clang and gcc have improved compliance (substantially) as outlined above, and their error messages have improved considerably as well (Clang has placed a strong emphasis on better error messages, almost from its inception).
Bottom line: I'd still recommend having at least two compilers installed and available, but today I'd probably choose different compilers than I did when I originally wrote this answer.
从长远来看,“不破坏任何东西”是一种滑坡,最好完全避免它。我公司的主要产品比几代编译器(首次于 1991 年使用 RW 编写)的寿命更长,每当需要迁移到较新的开发系统时,都要花费大量精力来梳理编译器扩展和安静的标准违规行为。
但只要有一个选项可以关闭或至少警告“非标准扩展”,我就可以接受。
34、70、6。
"Not breaking anything" is such a slippery slope in the long run, that it's better to avoid it altogether. My company's main product outlived several generations of compilers (first written in 1991, with RW), and combing through compiler extensions and quiet standards violations whenever it was the time to migrate to a newer dev system took a lot of effort.
But as long as there's an option to turn off or at least warn about 'non-standard extension', I'm good with it.
34, 70, 6.
我当然想要一个禁用语言扩展的选项来禁用所有语言扩展。为什么?
“更好”是一个主观词。语言扩展对于某些开发人员来说很有用,但对于其他开发人员来说却变得更加困难。
I would certainly want an option that disables language extensions to disable all language extensions. Why?
"Better" is a subjective word. Language extensions are useful for some developers, but make things more difficult for others.
我认为,如果编译器想成为开发时使用的主要模式,那么提供纯标准模式至关重要。当然,所有编译器都应该编译符合标准的代码,但如果它们不认为自己是主编译器,那么它们不扩展并不重要——例如,交叉编译器或较少的编译器流行的平台几乎总是被移植到,而不是有针对性的。
扩展对于任何编译器来说都很好,但是如果我需要的话必须打开它们,那就太好了。默认情况下,我更喜欢仅标准的编译器。
因此,鉴于此,我希望 MSVC 默认情况下仅是标准。与 gcc++ 相同。
统计数据:40、90、15
I think that it's critical that a compiler provide a standards-only mode if it wants to be the primary one used while developing. All compilers should, of course, compile standards compliant code, but it's not critical they they don't extend if they don't think of themselves as the primary compiler -- for example, a cross-compiler, or a compiler for a less popular platform that is nearly always ported to, rather than targeted.
Extensions are fine for any compiler, but it would be nice if I had to turn them on if I want them. By default, I'd prefer a standards-only compiler.
So, given that, I expect MSVC to be standards-only by default. The same with gcc++.
Stats: 40, 90, 15
我认为遵守标准非常重要。
我始终认为源代码更适合人类读者而不是机器。因此,为了向读者传达程序员的意图,遵守标准就像说一种最小公分母的语言。
无论是在家里还是在工作中,我都使用 g++,并且我使用以下标志为其别名,以严格遵守标准。
查看此页面严格 ANSI/ISO
我不是标准专家,但这对我很有帮助。我编写了 STL 风格的容器库,它们可以在不同的平台上按原样运行,例如 32 位 linux、64 位 linux、32 位 Solaris 和 32 位嵌入式 OSE。
I think standards compliance is very important.
I always consider source code is more for the human readers than for the machine(s). So, to communicate programmer's intention to the reader, abiding the standard is like speaking a language of lowest common denominator.
Both at home and work, I use g++, and I have aliased it with the following flags for strict standard compliance.
Check out this page on Strict ANSI/ISO
I am not a standards expert, but this has served me well. I have written STL-style container libraries which run as-is on different platforms, e.g. 32-bit linux, 64-bit linux, 32-bit solaris, and 32-bit embedded OSE.
考虑汽车上的指示灯(在某些司法管辖区称为“转向灯”);它们是一种可靠的方法,可以确定某人要关闭环岛的方向......直到只有一个人根本不使用它们。然后整个系统崩溃了。
当 IE 允许将
document.someId
用作document.getElementById('someId')
....然而,它确实催生了整整一代的程序员,甚至书籍,因此认为它是好的和正确的,因为“它有效”。然后,突然间,所生成的一千万个网站完全不可移植。标准对于互操作性很重要,如果您不遵循它们,那么拥有它们就毫无意义。
标准合规者可能会因“迂腐”而受到憎恨,但实际上,除非每个人都效仿,否则您将永远遇到可移植性和兼容性问题。
Consider indicators on cars (known as "turn signals" in some jurisdictions); they are a reliable way to determine which direction someone's going to turn off a roundabout... until just one person doesn't use them at all. Then the whole system breaks down.
It didn't "hurt anyone" or obviously "break anything" in IE when they allowed
document.someId
to be used as a shortcut fordocument.getElementById('someId')
.... however, it did spawn an entire generation of coders and even books that consequently thought it was okay and right, because "it works". Then, suddenly, the ten million resulting websites were entirely non-portable.Standards are important for interoperability, and if you don't follow them then there's little point in having them at all.
Standards-compliance hounds may get hated for "pedanticism" but, really, until everybody follows suit you're going to have portability and compatibility problems for ever.
标准合规性的重要性取决于您想要实现的目标。
如果您正在编写一个永远不会移植到当前环境之外的程序(特别是您不打算长期开发/支持的程序),那么它并不是很重要。无论什么有效,都有效。
如果您需要您的程序长期保持相关性,并且可以轻松移植到不同的环境,那么您会希望它符合标准,因为这是(或多或少)保证它在任何地方都能工作的唯一方法。
当然,诀窍在于弄清楚您实际上处于哪种情况。在开始一个程序时,认为它是一个短期黑客,然后发现它非常有用,以至于您仍然在开发/维护它多年,这是很常见的之后。在这种情况下,如果您在程序生命周期之初没有做出任何短视的设计决策,那么您的生活将不会那么不愉快。
How important standards-compliance is depends on what you are trying to achieve.
If you are writing a program that will never be ported outside of its current environment (especially a program that you're not planning to develop/support for a long time) then it's not very important. Whatever works, works.
If you need your program to remain relevant for a long time, and be easily portable to different environments, than you will want it to be standards compliant, since that's the only way to (more or less) guarantee that it will work everywhere.
The trick, of course, is figuring out which situation you are actually in. It's very common to start a program thinking it is a short-term hack, and later on find that it's so useful that you're still developing/maintaining it years later. In that situation your life will be much less unpleasant if you didn't make any short-sighted design decisions at the beginning of the program's lifetime.