C++ translation unit & anonymous namespace(unnamed namespace)
translation unit
在進入unnamed namespace前,必須先有translation unit的概念。以下段落摘自What is a “translation unit” in C++:
A translation unit is the basic unit of compilation in C++.
It consists of the contents of a single source file,
plus the contents of any header files directly or indirectly included by it,
minus those lines that were ignored using conditional preprocessing statements.
A single translation unit can be compiled into an object file,
library, or executable program.
The notion of a translation unit is most often mentioned in the
contexts of the One Definition Rule, and templates.
一個translation unit由"一個"source file,及其引入的數個header files,減去那些因預處理而被忽略的代碼。
一個translation unit會被編譯成一個object file,library,或是可執行檔。
anonymous namespace(unnamed namespace)
unnamed namespace的作用是讓它所包含的變數或函數只能被其所屬的translation unit所見。
在C語言裡,我們用static
修飾字來修飾函數來達到同樣的功能,但是使用unnamed namespace是比較被鼓勵的,詳見:Superiority of unnamed namespace over static?。
以下是在TensorRT/samples/common/logging.h
中定義的unnamed namespace:
namespace
{
//...
inline LogStreamConsumer LOG_INFO(const Logger& logger)
{
return LogStreamConsumer(logger.getReportableSeverity(), Severity::kINFO);
}
//...
} // anonymous namespace
我們先來看看這段代碼屬於哪個translation unit?因為logger.cpp
中引用了logging.h
,所以這段代碼與logger.cpp
同屬一個translation unit。
那麼為何這裡會特別使用unnamed namespace把LOG_INFO
等函數包起來呢?
筆者猜測可能是因為syslog.h
中也定義了LOG_INFO
函數,而可能在某些情況下syslog.h
及logging.h
會被一同編譯,這時如果沒做unnamed namespace的保護措施的話,就會出現linker error。
所以這裡才會使用unnamed namespace,來限制能看到此處定義的LOG_INFO
等函數的範圍。
Issue:根據Header files should not contain unnamed namespaces,把unnamed namespace定義在header文件中是不被鼓勵的。
參考連結
What is a “translation unit” in C++
Header files should not contain unnamed namespaces
C++ Tutorial – Namespaces and anonymous namespaces
namespace in C++ | Set 2 (Extending namespace and Unnamed namespace)
Superiority of unnamed namespace over static?
Why are unnamed namespaces used and what are their benefits?
Unnamed / anonymous namespaces vs static in namespace