내부 연결로 정의 된 전역 extern const 변수를 사용하는 클래스
-
26-12-2019 - |
문제
이 상황이 있습니다 :
// Test.h
extern const int param;
class Test
{
private:
int i;
public:
int foo();
};
.
및
// Test.cpp
#include "Test.h"
int Test::foo() { return param*10; }
.
및
// core.h
#include "Test.h"
const int param = 1; // should have internal linkage later in core.cpp
int do_stuff ();
.
및
// core.cpp
#include "core.h"
int do_stuff () { Test obj; return obj.foo(); }
int main() { return do_stuff(); }
.
그러나 링커 오류가 없습니다.링커는 Test.cpp를 어떻게 볼 수 있습니다. core.cpp에서 정의 된 Core.h를 통과하는 const int param
(const 정의의 기본값에 대한 기본값)?
core.h를 다시 작성할 때 (두 줄 바꾸기) :
// core.h
const int param = 1;
#include "Test.h"
int do_stuff ();
.
param
가 누락 된 링커 오류가 있습니다.그리고 나서, 내가 이것을 바꿀 때 :
// core.h
extern const int param = 1;
#include "Test.h"
int do_stuff ();
.
모두 다시 작동합니다.
나는 원래 상황에서 core.cpp 내부의 클래스 테스트가 자동으로 인출되는 것으로 생각되므로 test.cpp가 존재하지 않고 전체 코드가 core.cpp에있는 것입니다.왜 그렇다면 이유는 core.h에서 두 줄을 변화시키는 것에 의존해야합니까?
해결책
const 정의의 내부 연결에 대한 가정은 항상 사실이 아닙니다. Standart 섹션 3.5 Program linkage
, p를 참조하십시오. 3 (N3690 인용) :
네임 스페이스 범위 (3.3.6)가있는 이름은
의 이름 인 경우 내부 연결이 있습니다.
정적으로 명시 적으로 선언 된 변수, 기능 또는 기능 템플릿; 또는
외부 링키지 에 이전에 선언 된 extern 또는 을 명시 적으로 선언하고 명시 적으로 선언 한 비 휘발성 변수; 또는
익명 노조의 데이터 멤버.
첫 번째 케이스 param
에는 외부 연결이 있고 모든 것이 괜찮습니다.
두 번째 경우에는 core.cpp에 내부 연결 param
가 있지만 외부 링키지를 갖는 다른 선언 전용 param
가 있지만 정의는 없습니다.
세 번째 경우에는 param
가 다시 있습니다.