2017-09-08 1 views
12

우리가 헤더 foo.h 포함을 상상해 다음C++ 표준 : 네임 스페이스 범위의 constexpr 변수에 내부 연결이 있습니까?

#ifndef FOO_H_ 
#define FOO_H_ 

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

#endif // FOO_H_ 

foo::kSomeStringfoo.h를 포함하는 모든 번역 단위 내부 연결이 보장되어 있습니까? 이것은 C++ 11과 C++ 17간에 차이가 있습니까? 표준 초안 [basic.link]/3에서

는 이름이면 공간 범위를 갖는 이름 내부 결합을 갖는다 ...] 비 휘발성 CONST 수식 형의 비 인라인 변수가

말한다 명시 적으로 extern을 선언하지 않았거나 이전에 외부 연결을 선언했다. [...]

그러나 constexpr이 "const-qualified"로 간주되는지는 알 수 없습니다. 표준이 어딘가에 그렇게 말합니까?

내부 연결이 보장된다고 가정하면,이 용도로 ODR에 문제가없는 것처럼 보입니다. 맞습니까? (this answer에있는 것과는 대조적으로)

+0

예, 'constexpr'은 선언에서 C++ 11에서'const'를 의미합니다. C++ 14 이상에서는 멤버 함수가 아닌 변수에 대해서만 const를 의미합니다. –

+0

감사! 표준의 어느 섹션에서 그렇게 쓰는지 알고 있습니까? – jacobsa

답변

13

예, 객체 선언에 대한 constexpr은 객체가 const임을 의미합니다. [dcl.constexpr]/9을 참조하십시오. 예, 즉, 귀하의 예에서 kSomeString에는 내부 연결이 있음을 의미합니다.

여기서 우리가 말하는 ODR 위반의 종류는 kSomeString의 정의가 아니라 사용하려고하는 다른 정의입니다. 내부 연결 때문에 문제가 정확하게 발생합니다. 고려 :

void f(const std::string_view &); 

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

여러 번역 단위에 포함 된 경우는 ODR 위반이며, 각 번역 단위 g의 정의가 다른 개체를 참조 본질적 때문이다.

+0

감사합니다! ODR 문제의 예는 의미가 있습니다. 'g'는 각 번역 단위에서 동일하지 않습니다. 인라인 함수를 포함하지 않는 문제가있을 수 있습니까? – jacobsa