2013-05-27 35 views
3

我一直认为,如果你做#include <cheader>(其中header就像STDIO/STDLIB /串一些标准C++头),它是相同的是#include <header.h>,但裹入std命名空间。那么代码片段如何编译(g ++ 4.7.3)?为什么使用<cheader>代替<header.h>?

#include <cstdlib> 
int main() 
{ 
    malloc(1); 
    return 0; 
} 

为什么一个包括<cstdio>然后(而不是<stdio.h>)如果标准C函数将在全局命名空间呢?

而第二个问题是 - 我应该怎么做才能一些功能进行全局命名空间的(同时使用C++头文件在同一时间)?举例来说,我不想malloc是在全局命名空间,因为我有一个家庭作业:写我自己的内存分配器(特别是mallocfree功能),我会编译成动态库,并使用插入任何程序LD_PRELOAD

+1

因为不幸的是,实现*允许*名称在'std ::'名称空间之外,以及* required *在它们之内。 – juanchopanza

+0

@juanchopanza但如果我们允许标准头文件混淆全局名称空间,那么使用名称空间'std'有什么意义? – karlicoss

+0

@ karlicoss!这就是为什么我认为这是“不幸”。它仅适用于来自标准C库的名称。所有标准的C++函数和类型都在'std ::'命名空间中。 – juanchopanza

回答

4

如何的代码片断然后编译(克++ 4.7.3)?

因为C++ 11标准规定的17.6.1.2/4:

[...]这是 不确定是否这些名称是全局命名空间范围内的第一个声明,然后通过明确注入 到名字空间std使用申述(7.3.3)。

因此,允许实现在全局名称空间中定义这些实体。

为什么要包括那么(而不是)如果标准C函数将在全局命名空间呢?

首先,作为良好的作风问题。包括<stdio.h>给你确定性所有的实体在全局命名空间中定义,而包括<cstdio>给你的肯定,这些实体是一个你可以(在std命名空间),与可能(但不是一定)这些名称也可能出现在全局名称空间中,这是不必要的缺点。

我应该怎么做才能从全局命名空间中获取这些功能(同时使用C++头文件)?

不幸的是,你不能让一个实体了它生活在命名空间的。但是你可以(从您的实现骂开)做的是避免使用标准C函数完全,并且更喜欢使用从功能C++标准库。这些保证住在std命名空间。

因此,举例来说,如果你必须执行低级别的内存管理,而不是使用mallocnew操作。另外,请注意“必须对”的强调:大多数情况下,您应该使用RAII封装(如智能指针或标准容器),以避免必须应对低级内存管理,即newdelete

+0

是的,如果我必须编写一些C++应用程序,我肯定会使用'new'运算符,RAII和其他东西。但是,我必须编写内存分配器,其他程序(如'gcc'或'vim'等二进制文件)将使用该分配器。我只能使用非常低级别的内存抽象,比如那个赋值中的'mmap'系统调用。 – karlicoss

+0

@ karlicoss:我不确定我明白你为什么不能使用'new'运算符;特别是我不确定我是否理解这部分:“*我必须编写内存分配器,其他程序(二进制文件,如gcc或vim或其他)将使用*”。但是,我不需要了解,只要你知道你在做什么;)无论如何,这个故事的道理是:你不能从它声明的命名空间中取出一个实体,但是你应该*希望你的实现将在'std'命名空间中声明它们。如果不是这样的话,至少你做了你的部分,包括正确的标题。 –

+0

,因为'new'和'delete'仍然是这个家庭任务的高级内存抽象。那么,我必须实现一个内存管理库(使用'malloc','free','calloc'等),基本上我必须实现[heap](http://en.wikipedia.org/wiki/)堆_(编程))我自己。然后,我将运行'LD_PRELOAD = myallocator.so some_program'之类的东西,该程序将使用我的内存分配器,而不是'g ++'提供的内存分配器。 – karlicoss

相关问题