C ++中C库的范围 - <x.h> vs <cx> </cx> </x.h>

时间:2010-01-22 15:48:17

标签: c++ gcc gnu

C ++编程语言:特别版在第431页说明......

For every header < X.h > defining part of the C standard library in the global namespace and also in namespace std, there is a header < cX > defining the same names in the std namespace only.

但是,当我在&lt;中使用C头时cX&gt;样式,我不需要限定名称空间。例如......

#include <cmath>
void f() {
  double var = sqrt( 17 );
}

这样可以正常编译。即使这本书说使用&lt; cX&gt; header仅在std命名空间中定义名称,允许您使用这些名称而不限定命名空间。我在这里缺少什么?

P.S。使用GNU.GCC编译器

5 个答案:

答案 0 :(得分:9)

MSVC团队成员Stephan T. Lavavej在他的一篇博文(http://blogs.msdn.com/vcblog/archive/2008/08/28/the-mallocator.aspx#8904359)的评论中解决了这种情况的现实(以及对标准的一些改进):

  

&GT;此外,还应使用<cstddef><cstdlib>std::size_t等!

     

我曾经非常小心。 C ++ 98有一个灿烂的梦想,<cfoo&gt;将在命名空间std中声明所有内容,<foo.h>将包含<cfoo>,然后使用using-declarations将所有内容拖动到全局命名空间中。 (这是D.5 [depr.c.headers]。)

     很多实施者都忽略了这一点(其中一些实施者对C标准库头部几乎没有控制权)。因此,C ++ 0x已经改变以匹配现实。从N2723工作文件http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2723.pdf开始,现在<cfoo>保证在命名空间std中声明所有内容,并且可能会或可能不会在全局命名空间内声明内容。 <foo.h>正好相反:它保证在全局命名空间中声明所有内容,并且可能会或者可能不会在命名空间std中声明内容。

     

实际上,在C ++ 0x中,包括<cfoo>在内,无论如何都无法防范在全局命名空间中声明的所有内容。这就是为什么我不再费心<cfoo>

     

这是图书馆问题456,http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#456

     

(C ++ 0x仍然弃用C标准库中的<foo.h>标题,这很有趣。)

我与Lavavej达成了100%的协议,除非我第一次开始使用C ++时从未尝试过使用<cfoo>样式标题时非常小心 - 标准C语言太过根深蒂固了 - 那里使用它们时从来没有任何现实世界的问题(显然使用<cfoo>样式标题从来没有任何现实世界的好处。)

答案 1 :(得分:6)

C库的规则与名称空间的C ++库不同

gcc将Gcc docs中的标准解释为

  

该标准指定如果一个包含C样式头(在本例中为&lt; math.h&gt;),则符号将在全局命名空间中可用,并且可能在命名空间std ::中可用(但这不再是另一方面,包括C ++风格的头文件(&lt; cmath&gt;)保证了实体将在命名空间std中找到,也许在全局命名空间中找到。

在草案C0X ++规范中,它在17.6.2.3节标题中说明

  

未指定是否首先在全局命名空间范围内声明这些名称,然后注入这些名称   通过显式使用声明

进入命名空间std

答案 2 :(得分:4)

如果不实施两次C库,很难解决这个问题。见DR 456,基本上建议放弃这个问题。

答案 3 :(得分:1)

为什么当它违反标准时说“这会编译好”?谁允许您在不限定名称空间的情况下使用这些名称?您是否对特定实现进行了测试并发现它有效?

我强烈建议不要使用某些特定的非标准功能,因为它恰好适用于您选择的编译器。这样的事情很容易破坏,可能是同一个编译器的更高版本。

答案 4 :(得分:0)

您可能缺少使用符合标准的编译器(或您使用的编译器配置为与预标准代码兼容)。