在标题中声明的C函数是否保证在全局名称空间和std中?

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

据我所知,当你做#include 事情时,所有东西(当然除了宏)都在std:: namespace中声明。 我见过的每个实现都是通过执行以下操作来实现的:

 #include  namespace std { using ::abort; // etc.... } 

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

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

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

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

除第18条至第27条所述外,每个标题cname的内容应与ISO / IEC 9899:1990编程语言C(第7条)或ISO / IEC中规定的相应标题名称h的内容相同。 :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(但没有指明他们所在的任何其他范围)。

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

>还应该使用std::size_t等!

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

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

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

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

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

我自己从未喜欢过标题,并且发现我总是使用 。 现在我觉得我可以不再担心我在这方面缺乏C ++的“纯度”。

目前,没有。 事实上,即使代码适用于我现在的每个编译器,它实际上根本不应该工作 – #include其中一个c *头只能让你访问命名空间std里面的名字。

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

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