是在 <c____> 中声明的 C 函数标头保证在全局命名空间和标准中?
所以这是我一直想知道但一直不太确定的事情.所以这完全是出于好奇,而不是真正的问题.
So this is something that I've always wondered but was never quite sure about. So it is strictly a matter of curiosity, not a real problem.
据我了解,当您执行类似 #include <cstdlib>
之类的操作时,所有内容(当然宏除外)都在 std::
命名空间中声明.我见过的每个实现都是通过执行以下操作来实现的:
As far as I understand, whenyou do something like #include <cstdlib>
everything (except macros of course) are declared in the std::
namespace. Every implementation that I've ever seen does this by doing something like the following:
#include <stdlib.h>
namespace std {
using ::abort;
// etc....
}
这当然具有全局命名空间和 std
中的事物的效果.这种行为是否得到保证?或者是否有可能实现可以将这些东西放在 std
但不能放在全局命名空间中?我能想到的唯一方法是让你的 libstdc++ 实现每个 c 函数本身,将它们直接放在 std
中,而不是仅仅包括现有的 libc 头文件(因为没有删除某些东西的机制来自命名空间).这当然是付出了很多努力,却几乎没有任何好处.
Which of course has the effect of things being in both the global namespace and std
. Is this behavior guaranteed? Or is it possible that an implementation could put these things in std
but not in the global namespace? The only way I can think of to do that would be to have your libstdc++ implement every c function itself placing them in std
directly instead of just including the existing libc headers (because there is no mechanism to remove something from a namespace). Which is of course a lot of effort with little to no benefit.
我的问题的本质是,以下程序是否严格符合并保证工作?
The essence of my question is, is the following program strictly conforming and guaranteed to work?
#include <cstdio>
int main() {
::printf("hello world
");
}
我找到的最接近的是这个(17.4.1.2p4):
The closest I've found is this (17.4.1.2p4):
除非第 18 条至第27、每个头cname的内容应与对应的头文件名.h,如在 ISO/IEC 9899:1990 中规定编程语言 C(第 7 条),或ISO/IEC:1990 编程语言―C修正案 1:C 完整性,(第 7 条),视情况而定,就好像通过包含一样.在然而,C++ 标准库,声明和定义(定义为的名称除外C) 中的宏在命名空间内命名空间标准的范围(3.3.5).
Except as noted in clauses 18 through 27, the contents of each header cname shall be the same as that of the corresponding header name.h, as specified in ISO/IEC 9899:1990 Programming Languages C (Clause 7), or ISO/IEC:1990 Programming Languages―C AMENDMENT 1: C Integrity, (Clause 7), as appropriate, as if by inclusion. In the C + + Standard Library, however, the declarations and definitions (except for names which are defined as macros in C) are within namespace scope (3.3.5) of the namespace std.
说实话,我可以用任何一种方式解释.每个标头 cname 的内容应与相应标头 name.h 的内容相同,如 ISO/IEC 9899:1990 Programming Languages C 中所指定的那样"告诉我它们可能在全局命名空间中是必需的,但是在但是,C++ 标准库的声明和定义(名称除外)在 C 中定义为宏)在命名空间 std 的命名空间范围内(3.3.5)."表示它们在 std 中(但没有指定它们所在的任何其他范围).
which to be honest I could interpret either way. "the contents of each header cname shall be the same as that of the corresponding header name.h, as specified in ISO/IEC 9899:1990 Programming Languages C" tells me that they may be required in the global namespace, but "In the C + + Standard Library, however, the declarations and definitions (except for names which are defined as macros in C) are within namespace scope (3.3.5) of the namespace std." says they are in std (but doesn't specify any other scoped they are in).
推荐答案
下面是 MSVC 团队的 Stephan T. Lavavej (http://blogs.msdn.com/vcblog/archive/2008/08/28/the-mallocator.aspx#8904359):
Here's a nice synopsis of the situation (with some relaity vs. what the standard says) from Stephan T. Lavavej of the MSVC team (http://blogs.msdn.com/vcblog/archive/2008/08/28/the-mallocator.aspx#8904359):
>
还有 <cstddef>
、<cstdlib>
和 std::size_t
应该使用等!
>
also,<cstddef>
,<cstdlib>
, andstd::size_t
etc should be used!
我以前对此非常小心.C++98 有一个美好的梦想,其中 <cfoo>
将声明命名空间 std 中的所有内容,而 <foo.h>
将包含 <cfoo>
然后使用 using-declarations 将所有内容拖到全局命名空间中.(这是 D.5 [depr.c.headers].)
I used to be very careful about that. C++98 had a splendid dream wherein <cfoo>
would declare everything within namespace std, and <foo.h>
would include <cfoo>
and then drag everything into the global namespace with using-declarations. (This is 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 中声明事物.
This was ignored by lots of implementers (some of which had very little control over the C Standard Library headers). So, C++0x has been changed to match reality. As of the N2723 Working Paper, http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2723.pdf , now <cfoo>
is guaranteed to declare everything within namespace std, and may or may not declare things within the global namespace. <foo.h>
is the opposite: it is guaranteed to declare everything within the global namespace, and may or may not declare things within namespace std.
实际上,在 C++0x 中,包括 <cfoo>
并不能防止在全局命名空间中声明所有内容.这就是我不再为 <cfoo>
烦恼的原因.
In reality and in C++0x, including <cfoo>
is no safeguard against everything getting declared in the global namespace anyways. That's why I'm ceasing to bother with <cfoo>
.
这是图书馆第 456 期,http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#456 .
This was Library Issue 456, http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#456 .
(C++0x 仍然弃用 C 标准库中的头文件,这很有趣.)
(C++0x still deprecates the headers from the C Standard Library, which is hilarious.)
我自己从不喜欢 <cfoo>
标头,发现我一直使用 <foo.h>
.现在我觉得我可以不再为我在这方面缺乏 C++纯度"而焦虑了.
I've never been fond of the <cfoo>
headers myself, and found that I've always use <foo.h>
. Now I feel like I can stop being anxious about my lack of C++ 'purity' in that regard.
相关文章