[英]How would use of unnamed namespaces in headers cause ODR-violations?
在Google C ++樣式指南中, 命名空間部分指出“ 在頭文件中使用未命名的命名空間很容易導致違反C ++ One Definition Rule(ODR)。 ”
我理解為什么不在實現文件中使用未命名的命名空間可能會導致ODR違規,但不能在標頭中使用它們。 這怎么會導致違規?
原因是,如果您實際使用匿名命名空間中的任何內容,則存在未定義行為的風險。 例如:
namespace {
double const pi = 3.14159;
}
inline double twoPiR( double r ) { return 2.0 * pi * r; }
內聯函數(以及類和模板以及必須在多個翻譯單元中定義的任何其他內容)的規則是令牌必須相同(通常情況下,除非您點擊某個宏),並且所有符號必須相同地綁定。 在這種情況下,每個翻譯單元具有單獨的pi
實例,因此兩個twoPiR
的pi
綁定到每個翻譯單元中的不同實體。 (有一些例外,但它們都涉及整體表達。)
當然,即使沒有匿名命名空間,這也是未定義的行為(因為const
默認意味着內部鏈接),但基本原則成立。 在未命名的命名空間(或標頭中定義的任何const對象)中的任何內容的標頭中的任何使用都可能導致未定義的行為。 它是否是一個真正的問題取決於,但肯定涉及上述pi
的地址的任何事情都會引起問題。 (我在這里說“真的”,因為很多情況下地址或引用都是正式使用的,但實際上,內聯擴展會導致實際使用的值。當然,令牌3.14159
是3.14159
而不管它出現的地方。)
在test.h中
namespace {
int x;
}
namespace{
int x;
}
在任何源文件中包含該頭文件都會導致ODR違規,因為x
被定義了兩次。 發生這種情況是因為編譯器為未命名的命名空間賦予了唯一標識符,並且翻譯單元中所有出現的未命名命名空間都被賦予相同的標識符。 換句話說:每個TU最多只有一個未命名的命名空間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.