[英]private static member function or free function in anonymous namespace?
[英]free function inside anonymous namespace
//file.h
namespace Foo{
namespace{
void func(){}
}
}
VS
namespace Foo{
void func(){}
}
//file2.cpp use file.h's method
這兩種方法之間的調用代碼(例如,在可見性方面)有什么后果(如果有的話)?
這個:
namespace Foo {
namespace {
void func() {}
}
}
在很大程度上相當於:
namespace Foo {
static void func() {}
}
不同之處在於,在static
情況下,函數具有內部鏈接,因此鏈接器不可見。 在未命名的命名空間的情況下,該函數具有外部鏈接(對鏈接器可見),但是在您的其他源文件都不能“正常”訪問的名稱下。 如果您對編譯器的名稱修改方案進行反向工程,您仍然可以從不同的源文件調用該函數,並且該函數仍然列在目標文件的符號中,例如。
但常見的是,每個包含代碼的源文件(可能通過#include
the header file)都將包含自己的函數副本。 這可能會影響二進制文件的大小。
此外,如果由於某種原因需要第一個,你應該大量記錄它。 頭文件中的未命名命名空間通常是“WTF”點,您不希望在代碼中使用這些命名空間。 我必須說我想不出一個可行的用例。
兩種變體都允許在名稱Foo::func()
下找到該Foo::func()
。
但是,編譯器可能會在這兩種情況下生成不同的代碼。 在匿名命名空間內聲明一個函數會使該函數成為.cpp
文件的本地函數。 也就是說,包含頭部的每個.cpp
文件最終可能都有自己的(相同的) func
代碼實例化。 由於代碼重復,這可能會導致最終可執行文件中出現一些膨脹。
請注意,如果您定義內聯函數(如您的問題所示),這不是一個真正的問題,因為代碼將因內聯而被復制。
盡管如此,正如評論中所指出的:標題中的匿名名稱空間是不尋常的,並且會引起對此代碼的評論的懷疑。 你應該總是喜歡第二種選擇,除非你有充分的理由不這樣做。
第一個相當於:
namespace Foo
{
namespace TranslationUnitSpecific
{
void func();
}
}
這意味着每次包含標題時,都會聲明一個新的,不相關的func
實例。 如果func
不是inline
,則必須在使用它的每個源文件中定義它。 (另一方面,它確實意味着您可以在標題中提供實現而不使函數inline
。)
這也意味着您不能在標題中定義的inline
函數或模板函數中使用該函數,因為違反了一個定義規則,存在未定義的行為風險。
通常,如果有任何情況,您應該在標頭中使用未命名的命名空間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.