我并不真正理解翻译单元是什么以及如何使用未命名的命名空间:
如果我有一个.cpp文件:
namespace
{
void extFunction()
{
std::cout << "Called Unnamed Namespace's function.\n";
}
}和一个主要的.cpp文件:
#include <iostream>
#include "ext.cpp"
using namespace std;
int main()
{
extFunction();
return 0;
}为什么我可以从另一个文件访问未命名名称空间的成员?
编辑:
谢谢您的回复;但是,我如何使用未命名的名称空间,以及用于什么目的呢?
发布于 2019-03-31 19:00:01
翻译单元基本上是给编译器处理的代码块。编译器处理它并为链接器生成对象代码。链接器将来自所有翻译单元的目标代码组合成可执行文件。(有时,您会看到与此不同的详细信息,例如在只有一个翻译单元时看不到对象代码的文件。尽管实现细节可能有所不同,但这一概念仍然有效。
因此,通常在编译和翻译单元时生成的.o (或.obj)文件之间有一对一的对应关系。通常,每个.o文件都有一个.cpp文件。因此,通常认为每个.cpp文件都是它自己的翻译单元是合理的。直到你做了一些非常规的事。
当您使用#include指令时,您告诉编译器用包含的文件的全部内容替换这一行。也就是说,提供给编译器的代码块包括原始文件和包含文件的代码。如果将一个.cpp文件包含到另一个文件中,则给编译器的代码块将包含来自两个.cpp文件的代码,从而破坏了.cpp文件和翻译单元之间的等价性。这通常被认为是一个糟糕的想法。
让我们看一个例子。假设您有一个名为ext.cpp的文件,该文件包含以下内容:
namespace
{
void extFunction()
{
std::cout << "Called Unnamed Namespace's function.\n";
}
}另外,假设您有一个名为main.cpp的文件,该文件包含以下内容:
#include <iostream>
#include "ext.cpp"
int main()
{
extFunction();
return 0;
}如果要编译main.cpp,编译器首先要做的事情之一就是对main.cpp进行预处理。这会修改文件的内容,从而改变编译器所看到的内容。预处理后,编译器将处理的代码块如下所示。
[lots of code from the library header named "iostream"]
namespace
{
void extFunction()
{
std::cout << "Called Unnamed Namespace's function.\n";
}
}
int main()
{
extFunction();
return 0;
}此时,调用extFunction没有问题,因为编译器在它正在处理的代码块中看到了未命名的命名空间。
有关使用未命名命名空间的请求信息的另一个示例。类似于上面的,但不同。假设您有一个名为ext.cpp的文件,该文件包含以下内容:
#include <iostream>
namespace
{
void extFunction()
{
std::cout << "Called Unnamed Namespace's function in EXT.\n";
}
}
void extPublic()
{
extFunction();
}让我们还提供一个标头(ext.h),它将声明具有外部链接的函数。
void extPublic();现在转到main.cpp
#include <iostream>
#include "ext.h" // <-- Including the header, not the source.
namespace
{
void extFunction()
{
std::cout << "Called Unnamed Namespace's function in MAIN.\n";
}
}
int main()
{
extFunction();
extPublic();
return 0;
}看那儿!函数有两个定义,名为extFunction!链接器不会被弄糊涂吗?不用谢。这些职能不在翻译单位之外,因此不存在冲突。如果编译main.cpp,编译ext.cpp,并将main.o和ext.o链接到单个可执行文件中,则会得到以下输出。
在MAIN中调用未命名的Namespace函数。 在EXT中调用未命名的Namespace函数。
未命名命名空间的一个好处是,您不必担心与另一个源文件的未命名命名空间中的名称冲突。(当项目扩展到包含数百个源文件时,这将带来更大的好处。)
https://stackoverflow.com/questions/55441843
复制相似问题