标准遵守有多重要?

时间:2010-10-12 15:57:21

标签: c++ standards-compliance

对于像C ++这样的语言,标准的存在是必须的。好的编译器会尽力(最好是大多数好的编译器)来遵守。许多编译器都有语言扩展,其中一些是标准允许的,其中一些不是。在后两种例子中:

  1. gcc的typeof

  2. microsoft的编译器允许纯虚函数声明同时具有纯指定符(= 0)和定义(标准禁止 - 我们不讨论为什么,这是另一个主题:)

  3. (还有很多其他例子)

    这两个示例在以下意义上都很有用:example1是一个非常有用的功能,它将在c ++ 0x中以不同的名称提供。 example2也很有用,而且微软决定不尊重没有意义的禁令。

    我很感激编译器提供语言扩展,帮助开发人员完成日常工作。但是这里有一个问题:不应该有一个选项,在设置时,要求编译器尽可能符合标准,无论它们是否与标准一致。例如,visual studio有这样一个选项,称为禁用语言扩展。但是,嘿,他们仍然允许示例2。

    我希望每个人都能正确理解我的问题。 MSVC允许example2是一件很棒的事情,我非常希望该功能符合标准。它不会破坏任何兼容的代码,它没有什么坏处。它只是不标准。

    当禁用语言扩展名设置为true时,您是否希望Microsoft禁用example2?请注意,单词microsoft,example2等是占位符:) 为什么呢?

    再次,只是为了确保。关键点在于:编译器是否需要提供兼容版本(可选地在设置中设置)(在其限制中,例如我不是在谈论导出),因为它们提供了一个非标准的更好的替代方案,并且是也许甚至是标准的超集,因此不会破坏任何东西。

8 个答案:

答案 0 :(得分:7)

标准合规性很重要,因为它使代码更易于维护。这表现在很多方面:

  • 从一个版本的编译器移植到另一个版本。我曾经不得不从VC6发布一个120万-LOC应用程序到VC9。 VC6因为非常不合规而臭名昭着,即使它是新的。即使在新编译器在最低级别拒绝的最高警告级别上,它也允许不符合规范的代码。如果代码首先以更加合规的方式编写,那么这个项目不会(不应该)花费3个月。

  • 从一个平台移植到另一个平台。正如您所说,当前的MS编译器具有语言扩展。其中一些是由其他平台上的编译器共享的,有些则不是。即使它们是共享的,行为也可能略有不同。编写符合规范的代码,而不是使用这些扩展代码,使得代码更正确。 “移植”变得简单地将树拉下来并进行重建,而不是挖掘应用程序的内容,试图找出3位错误的原因。

  • C ++由标准定义。编译器使用的扩展名会改变语言。如果您编写标准C ++而不是编译器支持的方言,那些了解C ++而不是编译器使用的方言的新程序员将会更快地加速。

答案 1 :(得分:4)

首先,回复几条评论。有问题的MS VC扩展是这样的:

struct extension { 
    virtual void func() = 0  { /* function body here */ }
};

标准允许你实现纯虚函数,但不是这样的“就地”,所以你必须写这样的东西:

struct standard { 
    virtual void func() = 0;
};

void standard::func() { ; }

关于最初的问题,是的,我认为编译器最好有一种模式,尽可能准确地遵循(并强制执行)标准。虽然大多数编译器都有,但结果并不一定 as 准确地表示您/我想要的标准。

至少IMO,关于这个问题的唯一答案是关心可移植性的人(至少使用)定期进行至少几个编译器。对于C ++,其中一个应该基于EDG前端;我认为它比其他大多数人具有更好的一致性。如果你定期使用英特尔的编译器,那很好。否则,我建议您获取Comeau C ++的副本;它只有50美元,它是最接近“参考”的东西。您也可以在线使用Comeau,但如果您经常使用它,那么您可以获得自己的副本。

不要听起来像EDG或Comeau shill或任何东西,但即使你不太关心可移植性,我建议不管怎么说 - 它通常会产生出色的错误信息。它干净,清晰的错误消息(全部都是这些)已经节省了足够的时间来多次支付编译器的费用。

编辑:再看一遍,一些建议看起来过时,特别是EDG / Comeau的建议。自从我最初写这篇文章以来的三年里,Clang已经从纯粹的实验发展到生产使用非常合理。同样,gcc维护者(IMO)也在一致性方面取得了很大进展。

在同一时间,Comeau还没有发布一个新版本的编译器,已经发布了C ++标准的新版本。因此,Comeau现在已经相当于现行标准(并且情况似乎变得更糟,而不是更好 - 委员会已经批准了一个可能成为C +的新标准的委员会草案14)。

因此,虽然我当时推荐了Comeau,但今天我很难(最好)这样做。幸运的是,它提供的大多数优势现在都可以在更多的主流编译器中使用 - 如上所述,Clang和gcc都提高了合规性(基本上),他们的错误信息也得到了显着改善(Clang已经几乎从一开始就非常强调更好的错误信息。

结论:我仍然建议安装至少两个编译器并且可用,但今天我可能会选择不同于我最初编写此答案时的编译器。

答案 2 :(得分:3)

从长远来看,“没有破坏任何东西”是如此滑坡,最好完全避开它。我公司的主要产品超过了几代编译器(1991年首次使用RW编写),并且无论何时迁移到较新的开发系统,通过编译器扩展和安静标准违规都需要花费很多精力。

但只要有选择关闭或至少警告“非标准扩展”,我就很擅长。 34,70,6。

答案 3 :(得分:3)

我当然想要一个禁用语言扩展来禁用所有语言扩展的选项。为什么呢?

  • 所有选项都应该按照他们的意思行事。
  • 有些人需要开发可移植代码,要求编译器只接受该语言的标准形式。

“更好”是一个主观词。语言扩展对某些开发人员很有用,但对其他人来说却更难。

答案 4 :(得分:2)

我认为如果编译器想要成为开发时使用的主要模式,那么编译器提供仅标准模式至关重要。当然,所有编译器都应该编译符合标准的代码,但是如果它们不认为自己是主要的编译器,它们就不会扩展并不重要 - 例如,交叉编译器或编译器流行的平台,几乎总是移植到,而不是目标。

对于任何编译器来说扩展都没问题,但是如果我需要它们就必须打开它们会很好。默认情况下,我更喜欢标准编译器。

因此,鉴于此,我希望MSVC默认为标准。与gcc ++相同。

统计数据:40,90,15

答案 5 :(得分:2)

我认为标准合规非常重要。

我一直认为源代码更适合人类读者而不是机器。因此,为了向读者传达程序员的意图,遵守标准就像说一种最低标准的语言。

无论是在家还是工作,我都使用g ++,并且我使用以下标志对其进行别名处理,以确保严格遵守标准。

-Wall -Wextra -ansi -pedantic -std=c++98

Strict ANSI/ISO

上查看此页面

我不是标准专家,但这对我很有帮助。我编写了STL样式的容器库,它们在不同的平台上按原样运行,例如: 32位Linux,64位Linux,32位solaris和32位嵌入式OSE。

答案 6 :(得分:2)

考虑汽车指标(在某些司法管辖区称为“转向信号”);它们是一种可靠的方法来确定某人将要关闭环形交叉口的方向...直到只有一个人根本不使用它们。然后整个系统崩溃了。

当他们允许document.someId作为document.getElementById('someId')的快捷方式时,它并没有“伤害任何人”或明显“破坏任何东西”....但是,它做了产生了整整一代的编码器甚至书籍,因此认为它没问题,因为“它有效”。然后,突然之间,一千万个结果网站完全不可携带。

标准对于互操作性很重要,如果你不遵循这些标准,那么根本就没有这一点。

标准兼容性猎犬可能会因为“迂腐”而受到憎恨,但实际上,在每个人都效仿之前,你将永远存在可移植性和兼容性问题。

答案 7 :(得分:1)

遵守标准的重要性取决于您要实现的目标。

如果您正在编写一个永远不会在其当前环境之外移植的程序(尤其是您不打算长期开发/支持的程序),那么它并不是非常重要。无论什么有效,都有效。

如果您需要您的程序长时间保持相关性,并且易于移植到不同的环境,那么您将希望它符合标准,因为这是(或多或少)保证它可以工作的唯一方法无处不在。

当然,诀窍在于弄清楚你实际处于哪种情况。开始一个程序认为这是一个短期的黑客攻击是非常普遍的,后来又发现它非常有用,你还在开发/几年后保持它。在这种情况下,如果你在节目开始时没有做出任何短视的设计决定,那么你的生活将会更加不愉快。