标准库是否符合标准?

时间:2011-06-24 15:21:33

标签: c++ gcc compiler-construction standards-compliance standard-library

标准库是否需要符合标准?我觉得标准库不符合标准。这种感觉的基础是编译器生成的错误消息。例如,某些时候GCC会给出错误消息,这些消息以前缀__gxx开头,而其他许多消息都是我现在不记得的。但是看到它们让我觉得这些是特定于编译器的消息,并且不同的编译器将无法编译由GCC提供的标准库,反之亦然。这是真的吗?

换句话说,问题可以是:

  • 一个编译器提供的标准库是否可以与其他编译器一起编译?
  • 当我们说特定的编译器符合标准时,自动是否意味着它附带的stdlib也符合标准?或者它只是意味着这个编译器可以编译我们编写的符合标准的代码?程序员?
  • 我可以在我的项目中使用由一个编译器提供的标准库,该项目使用不同的编译器来编译项目吗?可移植性是否与标准一致性相同?

这些问题在不同的角度来看待同样的问题。所以,当我们说编译器X是符合标准的时,请帮助我理解它究竟意味着什么。

8 个答案:

答案 0 :(得分:5)

标准库是实现的细节。在标准不要求它由'文件'[标题]组成的意义上,它甚至可能不被“编译”:

  

174)标题不一定是源文件,也不是由<分隔的序列。和>在标题名称中必须有效   源文件名(16.2)。

该标准仔细地简化了对实现的要求,因此库可以“内置”到编译器(a.k.a内在函数)。例如,扩展std命名空间或#defining标准库中使用的名称会为您提供未定义的行为。

答案 1 :(得分:4)

是的,标准库必须符合标准,但在此方面有相当大的灵活性。该标准不需要特定的函数实现,只要满足要求,实现就可以自由添加内部函数,属性....

请注意,符合标准的库有不同的概念,并且使用标准功能实现库。

关于以下具体问题:

  

一个编译器提供的标准库是否可以与其他编译器一起编译?

有些人会,有些则不会。标准库的实现可以使用编译器内在函数进行某些操作,只有一个平台而不是其他平台才能使用...某些STL实现可以使用不同的编译器进行编译,例如STLPort,Dinkumware(这也是VS中提供的,有一些VS修改)

  

当我们说某个特定的编译器符合标准时,它是否自动意味着它附带的stdlib也符合标准?或者它只是意味着这个编译器可以编译我们编写的符合标准的代码,程序员?

这意味着库必须符合要求,但同样,标准不强制要求库的实现,这些可以使用非标准扩展等,它们可以在一个编译器中工作,但可能不在其他编译器中。例如,考虑shared_ptr的实现,引用计数必须以原子方式更新,但当前标准中没有对整数进行原子操作,因此必须根据非标准功能实现。 / p>

  

我可以在我的项目中使用由一个编译器提供的标准库,该项目使用不同的编译器来编译项目吗?便携性是否与标准一致性相同?

不一定。

答案 2 :(得分:3)

  

标准库是否符合标准?我觉得标准库不符合标准。

根据定义,实现必须符合标准,符合标准,是的。

否则它不是C ++标准库的实现,而是其他一些实现。

  

当我们说特定编译器符合标准时,是否自动意味着它附带的stdlib也符合标准?

这取决于措辞,不是吗?如果工具链声称包含标准库的实现,则可以合理地假设它符合标准库。编译器可执行文件本身是兼容的并不是一回事,除非库实现内置于编译器可执行文件中。

但这只是文字游戏。

  

我可以在我的项目中使用由一个编译器提供的标准库,该项目使用不同的编译器来编译项目吗?便携性是否与标准一致性相同?

当然不是。两个符合要求的实现可能彼此完全不兼容。

  

例如,某些时候GCC会给出错误消息,这些消息以前缀__gxx开头,而其他许多消息都是我现在不记得的。

没关系。只要接口符合标准,工具链就可以实现库,但它会选择它。该标准并未说明实施不能在其工作中使用符号__gxx


顺便说一句

虽然, 表示程序员可能不会使用带有前导下划线的符号,在某些情况下!

您不允许[lib.requirements] / [requirements]使用以下任何名称:

  1. 包含两个连续的下划线,
  2. 以下划线开头,后跟大写字母
  3. 以下划线开头,位于全局命名空间
  4. 此外,在C ++ 0x中,保留了不以下划线开头的文字后缀。

答案 3 :(得分:1)

库的面向用户的API应该是标准的;但是,实施不是必须的。您正在看到一个这样的示例,其中函数的标准版本被替换为优化的变体(具有不同的名称,因为有时候只能在某些情况下替换,例如可以证明适当的对齐)。这也意味着一个编译器的标准库的实现可能无法由不同的编译器构建(这可能导致移植时的引导问题,但这是另一个问题)。

答案 4 :(得分:1)

  

当我们说编译器X是符合标准的

时,它究竟意味着什么

这意味着编译器为标准库提供了标准所要求的所有要求,并且实现本身符合标准中的所有要求。问题是,标准库的“要求”在通用界面之后非常宽松。

答案 5 :(得分:0)

标准库只需满足最小接口。在它的实现中它可以做任何想做的事情,因为,它是实现,虽然我很确定有一些标识符限制,以防止冲突。

标准库实现不必以任何方式移植。它们可以是,但远非必然。

答案 6 :(得分:0)

标准对标准库的接口施加了限制,而不是实现。它明确表示标准库头可以执行用户代码无法执行的操作......例如,__MACRO__NAME__保留用于实现。显然,只有实现才能将所有这些函数和类型实际放入命名空间std。

大多数情况下,可以编写“便携式”实现。但它可能性能较差......作为一个简单的例子,考虑offsetof宏的传统实现。它通常涉及解除引用空指针,这是正式未定义的行为,但由于实现知道其平台如何工作,这没关系。便携式版本不能这样做,因此它必须实际创建所提供类型的新实例,以保持所有内容的正常运行。

C ++ 0x中的相当多的类型特征可能需要编译器支持,这使得“可移植”实现介于困难和不可能之间。例如,没有标准的方法来分析任意类型是否为POD,这就是boost::is_pod在某些平台上通过专业化需要用户支持的原因。

还有一个考虑因素,即许多标准库不仅仅是标题库。其他位可以用完全不同的语言编写......只要它们都正确地连接在一起,就没关系了。如果运行时是在Lisp中实现的,那么显然它不会是符合C ++的代码,可以可靠地放入不同的编译器工具链中。

答案 7 :(得分:0)

  

一个编译器提供的标准库可以用其他编译器编译   编译器?

假设图书馆符合标准,是的(我知道这是鸡蛋和鸡蛋)。

  

当我们说特定编译器符合标准时,确实如此   它自动意味着stdlib   附带它也是   符合标准的?或者简单地说   表示此编译器可以编译   符合标准的代码   我们,程序员?

是的,虽然我不知道任何完全确认的编译器。请注意,符合我们程序员标准的标准与标准库不同。例如,允许实现使用包含__(双下划线)的标识符。

  

我可以使用一个编译器提供的标准库吗?   使用不同的项目   编译器编译项目?是   便携性如同   标准的一致性?

您应该能够编译并使用这样的库。您几乎肯定无法使用任何已编译的库文件(静态或动态)文件,因为名称修改会有所不同。