변환 단위 및 링크

C++ 프로그램에서 는 변수 또는 함수 이름과 같은 기호를 범위 내에서 여러 번 선언할 수 있습니다. 그러나 한 번만 정의할 수 있습니다. 이 규칙은 "ODR(하나의 정의 규칙)"입니다. 선언나중에 이름을 정의와 연결할 수 있는 충분한 정보와 함께 이름을 프로그램에 도입(또는 다시 도입)합니다. 정의이름을 소개하고 이름을 만드는 데 필요한 모든 정보를 제공합니다. 이름이 변수를 나타내는 경우 정의는 명시적으로 스토리지를 만들고 초기화합니다. 함수 정의시그니처와 함수 본문으로 구성됩니다. 클래스 정의는 클래스 이름 뒤에 모든 클래스 멤버를 나열하는 블록으로 구성됩니다. (멤버 함수의 본문은 필요에 따라 다른 파일에서 별도로 정의될 수 있습니다.)

다음 예제에서는 몇 가지 선언을 보여 줍니다.

int i;
int f(int x);
class C;

다음 예제에서는 몇 가지 정의를 보여 줍니다.

int i{42};
int f(int x){ return x * i; }
class C {
public:
   void DoSomething();
};

프로그램은 하나 이상의 번역 단위로 구성됩니다. 번역 단위는 구현 파일과 직접 또는 간접적으로 포함하는 모든 헤더로 구성됩니다. 구현 파일에는 일반적으로 파일 확장명이 .cpp 있거나 .cxx. 헤더 파일에는 일반적으로 확장명이 .h 있거나 .hpp. 각 번역 단위는 컴파일러에 의해 독립적으로 컴파일됩니다. 컴파일이 완료되면 링커는 컴파일된 번역 단위를 단일 프로그램에 병합합니다. ODR 규칙 위반은 일반적으로 링커 오류로 표시됩니다. 링커 오류는 동일한 이름이 둘 이상의 번역 단위에 정의되어 있을 때 발생합니다.

일반적으로 여러 파일에 변수를 표시할 수 있는 가장 좋은 방법은 헤더 파일에서 선언하는 것입니다. 그런 다음 선언이 #include 필요한 모든 .cpp 파일에 지시문을 추가합니다. 헤더 내용 주위에 포함 가드를 추가하면 헤더가 선언하는 이름이 각 번역 단위에 대해 한 번만 선언되도록 합니다. 하나의 구현 파일에서만 이름을 정의합니다.

C++20 에서는 모듈이 헤더 파일에 대한 향상된 대안으로 도입되었습니다.

경우에 따라 파일에서 전역 변수 또는 클래스 .cpp 를 선언해야 할 수 있습니다. 이러한 경우 컴파일러와 링커에 이름에 어떤 종류의 링크 가 있는지 알려주는 방법이 필요합니다. 링크 유형은 개체 이름이 한 파일에서만 표시되는지 아니면 모든 파일에만 표시되는지 여부를 지정합니다. 링크의 개념은 전역 이름에만 적용됩니다. 링크의 개념은 범위 내에서 선언된 이름에는 적용되지 않습니다. 범위는 함수 또는 클래스 정의와 같은 묶은 중괄호 집합에 의해 지정됩니다.

외부 링크 및 내부 링크

free 함수는 전역 또는 네임스페이스 범위에서 정의된 함수입니다. 비 const 전역 변수 및 무료 함수에는 기본적으로 외부 링크가 있으며 프로그램의 모든 번역 단위에서 볼 수 있습니다. 다른 전역 개체는 해당 이름을 가질 수 없습니다. 내부 링크가 있거나 링크가 없는 기호는 선언된 변환 단위 내에서만 표시됩니다. 이름에 내부 링크가 있는 경우 동일한 이름이 다른 번역 단위에 있을 수 있습니다. 클래스 정의 또는 함수 본문 내에서 선언된 변수에는 연결이 없습니다.

전역 이름은 명시적으로 로 선언하여 내부 링크가 있도록 강제 적용할 수 있습니다 static. 이 키워드(keyword) 선언된 것과 동일한 번역 단위로 표시 유형을 제한합니다. 이 컨텍스트 static 에서는 지역 변수에 적용할 때와 다른 것을 의미합니다.

다음 개체에는 기본적으로 내부 링크가 있습니다.

  • const 개체입니다.
  • constexpr 개체입니다.
  • typedef 개체입니다.
  • static 네임스페이스 범위의 개체

개체 외부 링크를 제공하려면 개체를 const 선언 extern 하고 값을 할당합니다.

extern const int value = 42;

자세한 내용은 extern를 참조하세요.

참고 항목

기본 개념