이 프로그램을 g ++ 및 clang ++로 컴파일합니다. 차이점은 다음과 같습니다.
g ++는 1을 인쇄하지만 clang ++는 2를 인쇄합니다.
g ++ : extern varible은 가장 짧은 범위에서 정의 된
것 같습니다
.
clang ++ : extern varible은 가장 짧은 전역 범위에서 정의됩니다.
C ++ 사양에 대한 사양이 있습니까?
main.cpp
#include <iostream>
static int i;
static int *p = &i;
int main() {
int i;
{
extern int i;
i = 1;
*p = 2;
std::cout << i << std::endl;
}
}
other.cpp
int i;
버전 : g ++ : 7.4.0 / clang ++ : 10.0.0
컴파일 : $ (CXX) main.cpp other.cpp -o extern.exe
답변
[basic.link/7] 은 표준의 관련 부분이어야합니다. 현재 초안에서는 다음과 같이 말합니다.
블록 범위에서 선언 된 함수의 이름과 블록 범위
extern
선언으로 선언 된 변수의 이름 은 연결되어 있습니다. 이러한 선언이 명명 된 모듈에 첨부되면 프로그램이 잘못 구성됩니다. 링크가있는 엔터티의 가시적 선언이있는 경우 가장 안쪽의 네임 스페이스 범위 외부에 선언 된 엔터티를 무시하면 두 범위의 선언이 동일한 선언 영역에 나타나면 블록 범위 선언이 (잘못된 형식으로) 다시 선언됩니다. 블록 범위 선언은 동일한 엔티티를 선언하고 이전 선언의 링크를 수신합니다. 일치하는 엔티티가 둘 이상인 경우 프로그램이 잘못 구성됩니다. 그렇지 않으면 일치하는 엔티티가 없으면 블록 범위 엔티티가 외부 링크를 수신합니다.번역 단위 내에서 동일한 엔터티가 내부 및 외부 연결로 선언 된 경우 프로그램이 잘못 구성됩니다.
다음 예제는 귀하의 경우와 거의 정확히 일치합니다.
static void f();
extern "C" void h();
static int i = 0; // #1
void g() {
extern void f(); // internal linkage
extern void h(); // C language linkage
int i; // #2: i has no linkage
{
extern void f(); // internal linkage
extern int i; // #3: external linkage, ill-formed
}
}
따라서 프로그램이 잘못 구성되어야합니다. 설명은 예제 아래에 있습니다.
2 번 줄에 선언이 없으면 3 번 줄의 선언이 1 번 줄의 선언과 연결됩니다. 그러나 내부 연계가있는 선언은 숨겨져 있기 때문에 # 3에 외부 연계가 제공되므로 프로그램이 잘못 작성됩니다.