在<c ____>标题中声明的C函数是否保证在全局名称空间中以及std?</c ____>

时间:2010-04-06 18:51:53

标签: c++ c namespaces

所以这是我一直想知道但却从未确定过的事情。所以这完全是好奇心问题,而不是真正的问题。

据我了解,当你做#include <cstdlib>之类的事情时,std::名称空间中会声明一切(当然除了宏)。我见过的每一个实现都是通过执行以下操作来实现的:

#include <stdlib.h>
namespace std {
    using ::abort;
    // etc....
}

当然,这会影响全局命名空间和std。这种行为有保证吗?或者实现是否可能将这些内容放在std中而不是全局命名空间中?我能想到的唯一方法是让你的libstdc ++实现每个c函数本身直接放在std而不是只包含现有的libc头(因为没有机制从命名空间中删除某些东西) )。这当然是很多努力,几乎没有任何好处。

我的问题的实质是,以下程序是否严格符合并保证有效?

#include <cstdio>
int main() {
    ::printf("hello world\n");
}

编辑:我发现的最接近的是(17.4.1.2p4):

  

除第18条至第18条所述外   27,每个头cname的内容   应与该的相同   对应的头名name.h,如   ISO / IEC 9899:1990中规定的   编程语言C(第7条),或   ISO / IEC:1990编程语言-C   修订1:C完整性,(第7条),   适当时,好像通过包含。在   但是,C ++标准库   声明和定义   (除了定义为的名称   C)中的宏在命名空间内   名称空间std。

的范围(3.3.5)

说实话,我可以解释任何一种方式。 “每个标题cname的内容应与相应标题name.h的内容相同,如ISO / IEC 9899:1990编程语言C中所规定的那样”告诉我它们可能在全局命名空间中是必需的,但是“在但是,C ++标准库的声明和定义(名称除外) 在C)中被定义为宏的是在命名空间std的命名空间范围(3.3.5)内。“它们是在std中(但是没有指定它们所在的任何其他范围)。

3 个答案:

答案 0 :(得分:8)

这是MSVC团队的Stephan T. Lavavej(http://blogs.msdn.com/vcblog/archive/2008/08/28/the-mallocator.aspx#8904359)的情况(有一些相关性与标准所说的)的简要概要:

  

>也应该使用<cstddef><cstdlib>std::size_t等等!

     

我曾经非常小心。 C ++ 98有一个美妙的梦想,其中<cfoo>将声明命名空间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标准库中的标题,这很有趣。)

我自己从未喜欢<cfoo>标题,并发现我一直使用<foo.h>。现在我觉得我可以不再担心我在这方面缺乏C ++的“纯度”。

答案 1 :(得分:4)

目前,没有。实际上,即使代码适用于我现在的每个编译器,它实际上应该可以工作 - #include其中一个c *头只应该给出您可以访问命名空间std。

中的名称

由于实现这一点非常痛苦(正确地要求将整个C库复制为正确名称空间中的C ++库),在C ++ 0x中他们已经改变了一些要求 - 您的代码现在已经<但是,允许工作(至少如果内存服务),它仍然不需要工作。

答案 2 :(得分:0)

我不能说标准,因为我还没有阅读它们,但可以想象一个C ++环境不是建立在C环境之上,或者C环境是基础C ++ API之上的兼容层。在这种情况下,可能无法做出这些保证。如果禁止这样的实现成为兼容的实现,我会感到惊讶。