代码之家  ›  专栏  ›  技术社区  ›  Armen Tsirunyan

遵守标准有多重要?

  •  10
  • Armen Tsirunyan  · 技术社区  · 14 年前

    对于C++这样的语言来说,标准的存在是必须的。优秀的编译器会尽最大努力(至少,大多数优秀的编译器都会做到这一点)。许多编译器都有语言扩展,其中一些是标准允许的,而有些则不是。后一类2个例子:

    1. 海湾合作委员会的类型

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

    (还有很多其他例子)

    这两个例子在下面的意义上都是有用的:ExpRe1是一个非常有用的特性,它将以不同的名称在C++ 0x中可用。示例2也很有用,微软已经决定不尊重毫无意义的禁令。

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

    我希望每个人都能正确理解我的问题。MSVC允许示例2是一件很好的事情,我非常希望该功能在标准中出现。它不会破坏任何兼容的代码,也不会做什么坏事。只是不规范而已。

    当disable language extensions设置为true时,是否希望Microsoft禁用example2?请注意,单词microsoft、example2等是占位符:) 为什么?

    再一次,只是为了确定。关键点是:如果编译器为某个特性提供了一个兼容的版本(可以在设置中设置)(在它的限制中,例如,我不是在谈论导出),当它们提供了一个更好的替代方案时,它不是标准的,甚至可能是标准的超集,因此不会破坏任何东西。

    8 回复  |  直到 11 年前
        1
  •  7
  •   John Dibling    14 年前

    标准遵从性之所以重要,是因为它使代码易于维护。这体现在很多方面:

    • 从编译器的一个版本移植到另一个版本。我曾经不得不将120万个loc应用程序从VC6发布到VC9。VC6因严重不合规而臭名昭著,即使它是新的。即使在新编译器拒绝的最高警告级别上,它也允许使用不符合的代码。如果代码是以一种更兼容的方式编写的,那么这个项目就不会( 不应该 )已经花了3个月。

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

    • C++是由标准定义的。编译器使用的扩展会更改语言。新的在线程序员知道C++,而不是编译器所使用的方言,如果你写的是标准C++,而不是你的编译器支持的方言,你会更快地得到更快的速度。

        2
  •  4
  •   Jerry Coffin    11 年前

    首先,回复几个评论。所讨论的MS VC扩展如下:

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

    该标准允许您实现纯虚拟函数,但不能像这样“就地”,因此您必须编写类似这样的函数:

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

    关于最初的问题,是的,我认为编译器最好有一个模式,在这个模式中它尽可能精确地遵循(并强制执行)标准。虽然大多数编译器都有这样的功能,但结果并不一定是 作为 如您/我所愿,准确表示标准。

    至少在我看来,解决这个问题的唯一办法是让那些关心便携性的人 使用 )至少有两个定期编译程序。对于C++,其中一个应该基于EDG前端;我相信它比大多数其他的有更好的一致性。如果你经常使用英特尔的编译器,那就好了。否则,我建议得到一个COMFO C++的拷贝,它只有50美元,它是最接近的“引用”可用的东西。你也可以在网上使用Comeau,但是如果你经常使用它,就值得一份你自己的。

    听起来不像EDG或Comeau Shill或其他什么,但即使您不太关心可移植性,我还是建议您获取一个副本——它通常会产生非常好的错误消息。它干净、清晰的错误消息(全部由它们自己)在过去的几年中节省了足够的时间来为编译器支付多次费用。

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

    与此同时,Comeau没有发布他们的编译器的一个新版本, C++标准有了新的版本。因此,科莫现在相当落后于目前的标准(情况似乎越来越糟,而不是更好-委员会已经批准了一份新的标准草案,很可能会成为C++ 14)。

    因此,尽管我当时推荐科莫大学,但我今天这样做(充其量)有困难。幸运的是,它所提供的大多数优势现在都可以在更多主流编译器中使用——如上文所述,CLang和GCC都大大提高了遵从性, 它们的错误消息也有了很大的改进(Clang几乎从一开始就非常重视更好的错误消息)。

    底线:我仍然建议至少安装两个编译器并提供它们,但今天我可能会选择不同于最初编写这个答案时所选择的编译器。

        3
  •  3
  •   Cubbi    14 年前

    从长远来看,“什么都不破”是一个很滑的斜坡,最好完全避免。我公司的主要产品超过了几代编译器(1991年第一次使用rw编写),每当需要迁移到更新的dev系统时,都要仔细检查编译器扩展和安静的标准冲突。

    但是,只要有一个选项可以关闭或者至少警告“非标准扩展”,我就很擅长。 34, 70, 6。

        4
  •  3
  •   Mike Seymour    14 年前

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

    • 所有的选择都应该照他们所说的去做。
    • 有些人需要开发可移植代码,需要一个只接受语言标准形式的编译器。

    “更好”是一个主观的词。语言扩展对一些开发人员很有用,但会使其他开发人员更加困难。

        5
  •  2
  •   Lou Franco    14 年前

    我认为,如果一个编译器想成为开发过程中使用的主要模式,那么它提供一个只支持标准的模式是至关重要的。当然,所有编译器都应该编译符合标准的代码,但是如果他们不认为自己是主编译器(例如,交叉编译器),或者是用于一个不太流行的平台(几乎总是移植到而不是目标平台上)的编译器,他们就不会扩展这些代码,这并不重要。

    扩展对于任何编译器都是可以的,但是如果我需要的话,必须打开它们,那就太好了。默认情况下,我更喜欢只使用标准的编译器。

    因此,考虑到这一点,我希望MSVC只是默认的标准。与gcc++相同。

    状态:40、90、15

        6
  •  2
  •   Arun    14 年前

    我认为遵守标准非常重要。

    我总是认为源代码更适合人类读者,而不是机器。因此,要将程序员的意图传达给读者,遵守标准就像说一种具有最低公分母的语言。

    无论是在家里还是在工作中,我都使用g++,为了严格遵守标准,我将它命名为以下标志。

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

    查看此页面 Strict ANSI/ISO

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

        7
  •  2
  •   Lightness Races in Orbit    11 年前

    考虑汽车上的指示器(在某些管辖区称为“转向灯”);它们是确定某人将要关闭环岛的方向的可靠方法…直到只有一个人根本不使用它们。然后整个系统就崩溃了。

    它没有“伤害任何人”,也没有明显的“破坏任何东西”。 document.someId 用作 document.getElementById('someId') …然而,它 产生整整一代的编码人员,甚至书籍,因此认为它是好的和正确的,因为“它工作”。然后,突然间,产生的1000万个网站完全不可移植。

    标准对于互操作性很重要,如果你不遵循它们,那么拥有它们就没有什么意义。

    标准遵从性的追随者可能会因为“学究主义”而被憎恨,但是,实际上,除非每个人都遵循这一原则,否则您将永远面临可移植性和兼容性问题。

        8
  •  1
  •   Jeremy Friesner    14 年前

    标准遵从性的重要性取决于您试图实现的目标。

    如果您正在编写一个永远不会移植到当前环境之外的程序(尤其是一个长期不打算开发/支持的程序),那么它就不是很重要了。不管怎样,都是有效的。

    如果你需要你的程序在很长一段时间内保持相关性,并且能够很容易地移植到不同的环境中,那么你就不希望它符合标准,因为这是保证它在任何地方都能工作的唯一方法(或多或少)。

    当然,诀窍是弄清楚你实际上处于哪种情况。启动一个程序,认为它是一个短期的黑客行为,这是很常见的,后来发现它是如此有用,以至于几年后您仍在开发/维护它。在这种情况下,如果你在项目的生命周期开始时没有做任何短视的设计决策,你的生活就不会那么不愉快了。