답변:
당신이 (구현 파일을 쓸 때 .cpp
, .cxx
등) 컴파일러는 생성 번역 단위를 . 이것은 구현의 소스 파일과 그 안에있는 모든 헤더 #include
입니다.
내부 연결 은 번역 단위의 범위에있는 모든 항목을 나타냅니다 .
외부 연결 은 특정 번역 단위를 넘어 존재하는 것들을 말합니다. 다시 말해, 모든 번역 단위 (또는 객체 파일)의 조합 인 전체 프로그램을 통해 액세스 할 수 있습니다 .
const
변수의 규칙 과 그 목적 에 대한 질문 이 완전히 빠져 있기 때문에이 답변은 불완전 합니다.
으로 dudewat 말했다 외부 연결은 기호 (함수 나 전역 변수) 프로그램 및 전체에 액세스 할 수있는 의미 내부 가 하나 개에서만 액세스 할 수 있다는 연계 수단 번역 단위 .
extern
및 static
키워드 를 사용하여 심볼의 연결을 명시 적으로 제어 할 수 있습니다 . 연계가 지정되지 않은 경우 기본 연계는 extern
비 const
기호 및 static
(내부) const
심볼에 대한 것 입니다.
// in namespace or global scope
int i; // extern by default
const int ci; // static by default
extern const int eci; // explicitly extern
static int si; // explicitly static
// the same goes for functions (but there are no const functions)
int foo(); // extern by default
static int bar(); // explicitly static
사용하는 대신 주 static
내부 연결을 위해 사용하는 것이 좋습니다 익명의 네임 스페이스 당신도 넣을 수 있습니다되는 class
말이지. 익명 네임 스페이스에 대한 연결은 C ++ 98과 C ++ 11 사이에서 변경되었지만 가장 중요한 것은 다른 번역 단위에서 접근 할 수 없다는 것입니다.
namespace {
int i; // external linkage but unreachable from other translation units.
class invisible_to_others { };
}
extern
다른 파일에 일치하는 선언 을 제공하여 범위를 포함하지 않는 범위로 확장 할 수 있습니다 .static
. 이러한 변수는 내부 연결 이 있다고합니다 .다음 예제를 고려하십시오.
void f(int i);
extern const int max = 10;
int n = 0;
int main()
{
int a;
//...
f(a);
//...
f(a);
//...
}
f
선언합니다 (기본값). 이 파일의 정의는이 파일 또는 다른 번역 단위 (아래에 제공됨)에서 나중에 제공해야합니다.f
max
정수 상수로 정의됩니다. 상수의 기본 연결은 internal 입니다. 키워드와의 연결이 외부로 변경되었습니다 extern
. 이제 max
다른 파일에서 액세스 할 수 있습니다.n
정수 변수로 정의됩니다. 함수 본문 외부에 정의 된 변수의 기본 연결은 external 입니다.#include <iostream>
using namespace std;
extern const int max;
extern int n;
static float z = 0.0;
void f(int i)
{
static int nCall = 0;
int a;
//...
nCall++;
n++;
//...
a = max * z;
//...
cout << "f() called " << nCall << " times." << endl;
}
max
외부 연결 을 갖도록 선언되었습니다 . max
일부 파일 에 (외부 링크가있는)에 대한 일치하는 정의 가 나타나야합니다. (1.cpp에서와 같이)n
외부 연결 을 갖도록 선언되었습니다 .z
되고 정의 와 전역 변수로 내부 링크 .nCall
지정 nCall
합니다 f()
. 기본 자동 스토리지 클래스가있는 로컬 변수와 달리 nCall
, 프로그램 시작시 한 번만 초기화되고을 호출 할 때마다 한 번만 초기화됩니다 f()
. 스토리지 클래스 지정자는 static
범위가 아닌 로컬 변수의 수명에 영향을줍니다.주의 : 키워드 static
는 두 가지 역할을합니다. 글로벌 변수의 정의에 사용될 때 내부 연결을 지정합니다 . 지역 변수의 정의에 사용될 때 변수의 수명이 함수의 지속 시간이 아닌 프로그램의 지속 시간이되도록 지정합니다.
희망이 도움이됩니다!
static
게으른 단일 초기화를 허용합니다 (글로벌 객체가 필요하지만 글로벌 생성 순서 문제로 인해 생성되는 시점을 제어해야하며 동적으로 할당 할 수없는 경우 유용해야 함) 사용하여 new
암시 적으로,이) C ++를 사용하는 임베디드 시스템에 문제가 주로, 더 깊이 초기화 제도가 해당 개체에 필요한 것 이상이 될 수도있다.
'C'의 다른 범위에 대해 이야기 할 수 있습니다
범위 : 기본적으로 얼마나 오래 볼 수 있고 얼마나 멀리 있습니다.
지역 변수 : 범위는 함수 안에 만 있습니다. RAM의 STACK 영역에 있습니다. 즉, 함수가 호출 될 때마다 함수 인수를 포함하여 해당 함수의 일부인 모든 변수가 새로 만들어 져서 컨트롤이 함수를 벗어나면 소멸됩니다. (함수가 반환 될 때마다 스택이 플러시되므로)
정적 변수 : 이것의 범위는 파일입니다.
선언 된 파일의 모든 위치에 액세스 할 수 있습니다 . RAM의 DATA 세그먼트에 상주합니다. 파일 내부에서만 액세스 할 수 있으므로 내부 링크가 가능합니다. 모든
다른 파일이 변수를 볼 수 없습니다. 사실 STATIC 키워드는
'C'에 일정 수준의 데이터 또는 함수 숨기기를 도입 할 수있는 유일한 방법입니다.
전역 변수 : 이것의 범위는 전체 응용 프로그램을위한 것입니다. 응용 프로그램의 모든 곳에서 액세스 할 수 있습니다. 전역 변수도 DATA 세그먼트에 상주합니다. 응용 프로그램의 모든 위치에 액세스 할 수 있으므로 EXTERNAL Linkage
기본적으로 모든 기능은 전역입니다. 파일 외부에서 일부 함수를 숨겨야하는 경우 정적 키워드를 함수 앞에 붙일 수 있습니다. :-)
질문에 대해 이야기하기 전에 번역 단위 , 프로그램 및 C ++의 기본 개념 (실제로 연결은 일반적으로 그중 하나임) 이라는 용어를 정확하게 아는 것이 좋습니다 . 또한 범위 가 무엇인지 알아야합니다 .
몇 가지 핵심 사항을 강조하겠습니다. 이전 답변에서 누락 된 사람들.
연결 은 이름 의 속성이며 선언에 의해 소개됩니다 . 다른 이름은 동일한 개체 (일반적으로 개체 또는 함수)를 나타낼 수 있습니다 . 따라서 엔터티의 연결 에 대해 말하는 것은 일반적으로 엔터티가 특정 선언 (일반적으로 하나의 선언)에서 고유 한 이름으로 만 참조된다고 확신하지 않는 한 무의미합니다.
주 목적은 실체이지만, 변수는 아니다. 변수의 연결에 대해 이야기하는 동안 실제로 표시된 엔티티 (특정 선언에 의해 도입 된)의 이름이 관련됩니다. 이름의 연결은 연결 없음, 내부 연결 또는 외부 연결 중 하나에 속합니다.
다른 번역 단위는 헤더 / 소스 파일 (예, 표준 문구) 포함으로 동일한 선언을 공유 할 수 있습니다. 따라서 다른 번역 단위에서 동일한 이름을 참조 할 수 있습니다. 선언 된 이름에 외부 연결이있는 경우 해당 이름으로 참조 된 엔티티의 ID도 공유됩니다. 선언 된 이름에 내부 연결이있는 경우 다른 번역 단위에서 동일한 이름이 다른 엔터티를 나타내지 만 동일한 번역 단위의 다른 범위에서 엔터티를 참조 할 수 있습니다. 이름에 연결이없는 경우 다른 범위의 엔터티를 참조 할 수 없습니다.
(죄송합니다 ... 입력 한 내용이 다소 표준 문구를 반복 하는 것으로 나타났습니다 ...)
언어 사양에 포함되지 않는 다른 혼란스러운 점들도 있습니다.
__attribute__
또는__declspec
) 또는 컴파일러 옵션을 사용할 수 있으며 이미지가 전체 프로그램 또는 번역 단위에서 번역 된 객체 파일이 아니므로 표준 개념으로 정확하게 설명 할 수 없습니다. C ++에서 symbol은 규범적인 용어가 아니기 때문에 관련 방언의 확장이 널리 채택되어 있어도 구현 세부 사항 일뿐입니다.네임 스페이스 범위 const
변수 의 연결 규칙은 특별합니다 (특히 const
C 언어로 파일 범위에서 선언 된 객체 와 다르며 식별자 연결이라는 개념이 있습니다). ODR 은 C ++에 의해 시행 되므로 함수를 제외하고 전체 프로그램에서 동일한 변수 또는 함수의 정의를 두 개 이상 유지하지 않는 것이 중요 inline
합니다 . 특별한 규칙이 없다면 const
, 여러 번역 단위 (또는 하나의 번역 단위로 여러 번 포함 된 헤더 또는 소스 파일 (종종 "헤더 파일")에 const
이니셜 라이저 (예 :)가 포함 된 가장 간단한 변수 선언 = xxx
, 그러나 드물게) 프로그램에서 ODR을 위반하여 사용하게됩니다.const
일부 객체와 유사한 매크로를 대체 할 수 없습니다.
C ++의 내부 및 외부 링크 는 명확하고 간결한 설명을 제공 한다고 생각 합니다.
변환 단위는 구현 (.c / .cpp) 파일 및 포함 된 모든 헤더 (.h / .hpp) 파일을 나타냅니다. 이러한 변환 단위 내의 개체 나 함수에 내부 연결이있는 경우 해당 변환 기호 내에서만 링커가 해당 심볼을 볼 수 있습니다. 개체 나 함수에 외부 연결이있는 경우 링커는 다른 변환 단위를 처리 할 때이를 볼 수도 있습니다. 글로벌 네임 스페이스에서 사용될 때 static 키워드는 심볼에 내부 링크가 있도록합니다. extern 키워드는 외부 링크가있는 심볼을 생성합니다.
컴파일러는 기본적으로 심볼 연결을 다음과 같이 지정합니다.
비 const 전역 변수에는 기본적으로 외부 연결이 있습니다
Const 전역 변수에는 기본적으로 내부 연결이 있습니다
함수에는 기본적으로 외부 연결이 있습니다
연결은 식별자가 다른 변환 단위로 표시 되더라도 동일한 이름을 가진 식별자가 동일한 객체, 함수 또는 다른 엔터티를 참조하는지 여부를 결정합니다. 식별자의 연결은 선언 방법에 따라 다릅니다. 연계에는 세 가지 유형이 있습니다.
C ++ 전용 : C ++과 비 C ++ 코드 단편 ( 언어 연계 라고 함)을 연계 할 수도 있습니다.
출처 : IBM 프로그램 연계
원래
extern linkage
변수는 모든 파일에서 볼 수 있습니다internal linkage
변수는 단일 파일에서 볼 수 있습니다.설명 : const 변수는 extern으로 달리 선언되지 않는 한 기본적으로 내부적으로 링크됩니다.
external linkage
const
전역 변수는internal linkage
extern const
전역 변수는external linkage
C ++의 링키지에 대한 꽤 좋은 자료
http://www.goldsborough.me/c/c++/linker/2016/03/30/19-34-25-internal_and_external_linkage_in_c++/
C ++에서
파일 범위에 있고 클래스 나 함수 안에 중첩되지 않은 모든 변수는 프로그램의 모든 변환 단위에서 볼 수 있습니다. 링크 타임에 이름이 해당 번역 단위 외부의 모든 링커에 표시되므로 외부 링크 라고 합니다.
전역 변수와 일반 함수에는 외부 연결이 있습니다.
파일 범위의 정적 객체 또는 함수 이름은 번역 단위에 로컬입니다. 이를 내부 연계 라고합니다
링크는 링크 /로드시 주소가있는 요소 만 나타냅니다. 따라서 클래스 선언과 지역 변수에는 연결이 없습니다.