簡體   English   中英

C ++標准:命名空間范圍的constexpr變量是否具有內部鏈接?

[英]C++ standard: do namespace-scoped constexpr variables have internal linkage?

想象一下,我們有一個包含以下內容的標題foo.h

#ifndef FOO_H_
#define FOO_H_

namespace foo {
constexpr std::string_view kSomeString = "blah";
}

#endif  // FOO_H_

foo::kSomeString保證在包含foo.h任何翻譯單元中都有內部鏈接? 這在C ++ 11和C ++ 17之間有所不同嗎?

在草案標准[basic.link] / 3中

具有命名空間作用域的名稱具有內部鏈接,如果它是非易失性const限定類型的非內聯變量的名稱,該變量既未顯式聲明為extern,也未聲明為具有外部鏈接[...]

但我不知道constexpr算作“const-qualified”。 標准是否在某處說出來?

假設這保證具有內部鏈接,看起來ODR對此用法沒有問題,對吧? (與此答案中的內容形成鮮明對比。)

是的,對象聲明的constexpr意味着對象是const [dcl.constexpr] / 9 是的,這意味着您的示例中的kSomeString具有內部鏈接。

我們在這里討論的ODR違規種類不是kSomeString本身的定義,而是其他試圖使用它的定義。 正是由於內部聯系,存在一個問題。 考慮:

void f(const std::string_view &);

inline void g() { 
    f(foo::kSomeString); 
}

如果包含在多個翻譯單元中,這是ODR違規,主要是因為每個翻譯單元中g的定義引用了不同的對象。

您對kSomeString使用是完全有效的。

首先要做的事情; TC解釋說,你的對象是const限定的。 它還是文字類型 ,因為它有一個constexpr構造函數。 因此,如果在頭文件中定義的函數中使用它,則標准中的以下異常適用(第3.2章):

內聯函數可以有多個定義,外部鏈接(7.1.2),非靜態函數模板(14.5.6),(...)在程序中,每個定義出現在不同的翻譯單元中,並提供這些定義滿足以下要求。 鑒於這樣一個名為D的實體在多個翻譯單元中定義,那么

  • D的每個定義應由相同的令牌序列組成;
  • 在D的每個定義中,根據3.4查找的相應名稱,應指在D的定義中定義的實體,或者在重載決議(13.3)之后和部分模板專業化匹配之后應引用同一實體(14.8) .3), 除了如果對象在D的所有定義中具有相同的文字類型,並且該對象用常量表達式(5.19)初始化,並且值(但不使用對象的地址),並且對象在D的所有定義中具有相同的值 ;
  • (......)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM