所以这是我一直想知道但却从未确定过的事情。所以这完全是好奇心问题,而不是真正的问题。
据我了解,当你做#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中(但是没有指定它们所在的任何其他范围)。
答案 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有一个美妙的梦想,其中
很多实施者都忽略了这一点(其中一些实施者对C标准库头部几乎没有控制权)。因此,C ++ 0x已经改变以匹配现实。从N2723工作文件http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2723.pdf开始,现在<cfoo>
将声明命名空间std中的所有内容,<foo.h>
将包含<cfoo>
,然后使用using-declarations将所有内容拖动到全局命名空间中。 (这是D.5 [depr.c.headers]。)<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之上的兼容层。在这种情况下,可能无法做出这些保证。如果禁止这样的实现成为兼容的实现,我会感到惊讶。