在头文件中声明的C函数是否< c____>保证在全局名称空间和标准名称空间中?

goucqfw6  于 2022-12-22  发布在  其他
关注(0)|答案(3)|浏览(114)

所以这是我一直想知道的事情,但从来没有确定过。所以这完全是一个好奇心的问题,不是一个真实的的问题。
据我所知,当你做#include <cstdlib>这样的事情时,所有的东西(当然除了宏)都是在std::命名空间中声明的。我见过的每个实现都是通过做如下的事情来实现的:

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

当然,这会产生全局名称空间和std中的东西都存在的效果。实现每个c函数本身,将它们直接放置在std中,而不是仅包括现有的libc头(因为没有从名称空间中删除某些内容的机制)。这当然是一项很大的工作,几乎没有好处。
我问题的实质是,下面的程序是否严格符合并保证工作?

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

**编辑:**我找到的最接近的代码是(17.4.1.2p4):

除第18条至第27条中另有说明外,每个标题cname的内容应与ISO/IEC 9899:1990编程语言C(第7条)或ISO/IEC:1990编程语言-C修正案1中规定的相应标题name. h的内容相同:C完整性(第7条),视情况而定,就像包含一样。然而,在C标准库中,声明和定义(除了在C中定义为宏的名称)在命名空间std的命名空间范围(3.3.5)内。
老实说,我可以用任何一种方式来解释。“每个头cname的内容应该与相应的头name. h的内容相同,如ISO/IEC 9899:1990编程语言C中所规定的”告诉我,它们可能在全局名称空间中是必需的,但“然而,在C
标准库中,声明和定义(除了在C中定义为宏的名称)在名称空间std的名称空间作用域(3.3.5)内。”说它们在std中(但没有指定它们所在的任何其他作用域)。

2ul0zpep

2ul0zpep1#

下面是MSVC团队的Stephan T. Lavavej对这种情况的一个很好的概述(有一些现实与标准所说的)(http://blogs.msdn.com/vcblog/archive/2008/08/28/the-mallocator.aspx#8904359):
还应使用><cstddef><cstdlib>std::size_t等!
C98有一个美好的梦想,<cfoo>可以声明std名称空间中的所有内容,<foo.h>可以包含<cfoo>,然后用using声明将所有内容拖到全局名称空间中(这是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内的内容。
实际上,在C0x中,包含<cfoo>并不能防止所有内容都在全局名称空间中声明,这就是为什么我不再为<cfoo>而烦恼。
这是图书馆第456期,http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#456。
(C
0x仍然反对使用<foo.h>C标准库中的头文件,这很搞笑。)
我自己从来都不喜欢<cfoo>头文件,我发现我一直都在使用<foo.h>,现在我觉得我可以不再担心我在这方面缺乏C++的“纯度”了。

wgxvkvu9

wgxvkvu92#

事实上,即使代码可以与我现在使用的每一个编译器一起工作,它也根本不应该工作--#include ing其中一个c* 头文件只应该给予您访问名称空间std内的名称。
由于实现这一点非常痛苦(要使它正确,基本上需要将整个C库复制为正确名称空间中的C库),在C 0x中,他们稍微改变了一些要求--现在代码可以工作,尽管(至少在内存服务的情况下)仍然不需要工作。

bqucvtff

bqucvtff3#

我不能为这些标准说话,因为我没有读过它们,但是人们可以想象一个不是建立在C环境之上的C环境,或者C环境是底层C API之上的一个兼容层。在这种情况下,这些保证可能就没有了。如果这样的实现被禁止成为一个兼容的实现,我会感到惊讶。

相关问题