다음을 통해 공유


extern(C++)

extern 키워드는 전역 변수, 함수 또는 템플릿 선언에 적용될 수 있습니다. 기호에 외부 링크가 있음을 지정합니다. 연결에 대한 백그라운드 정보와 전역 변수 사용이 권장되지 않는 이유는 변환 단위 및 연결을 참조하세요.

extern 키워드는 상황에 따라 네 가지 의미를 갖습니다.

  • const가 아닌 전역 변수 선언에서 extern은 변수 또는 함수가 다른 변환 단위에 정의되도록 지정합니다. 변수가 정의된 파일을 제외한 모든 파일에 extern을 적용해야 합니다.

  • const 변수 선언에서는 변수에 외부 링크가 있음을 지정합니다. extern은 모든 파일의 모든 선언에 적용되어야 합니다. (전역 const 변수에는 기본적으로 내부 연결이 있습니다.)

  • extern "C"는 함수가 다른 곳에서 정의되고 C 언어 호출 규칙을 사용함을 지정합니다. extern "C" 한정자는 블록의 여러 함수 선언에 적용될 수도 있습니다.

  • 템플릿 선언에서 extern은 템플릿이 이미 다른 곳에서 인스턴스화되었음을 지정합니다. extern은 현재 위치에 새 인스턴스를 만드는 대신 다른 인스턴스화를 다시 사용할 수 있음을 컴파일러에 알립니다. extern 사용에 대한 자세한 내용은 명시적 인스턴스화를 참조하세요.

extern가 아닌 전역에 대한 const 연결

링커가 전역 변수 선언 전에 extern을 보면 다른 변환 단위에서 정의를 찾습니다. 전역 범위에서 const 변수가 아닌 선언은 기본적으로 외부에 있습니다. 정의를 제공하지 않는 선언에만 extern을 적용합니다.

//fileA.cpp
int i = 42; // declaration and definition

//fileB.cpp
extern int i;  // declaration only. same as i in FileA

//fileC.cpp
extern int i;  // declaration only. same as i in FileA

//fileD.cpp
int i = 43; // LNK2005! 'i' already has a definition.
extern int i = 43; // same error (extern is ignored on definitions)

extern 전역에 대한 const 연결

const 전역 변수에는 기본적으로 내부 연결이 있습니다. 변수가 외부 링크를 갖도록 하려면 extern 키워드를 정의에 적용하고 다른 파일의 다른 모든 선언에 적용합니다.

//fileA.cpp
extern const int i = 42; // extern const definition

//fileB.cpp
extern const int i;  // declaration only. same as i in FileA

extern constexpr 링크

Visual Studio 2017 버전 15.3 이하에서는 변수가 constexpr으로 표시된 경우에도 컴파일러가 항상 extern 변수에 내부 연결을 제공했습니다. Visual Studio 2017 버전 15.5 이상에서는 /Zc:externConstexpr 컴파일러 스위치를 사용하여 올바른 표준 준수 동작을 사용하도록 설정합니다. 결국 옵션이 기본값이 됩니다. /permissive- 옵션은 /Zc:externConstexpr을 사용하도록 설정하지 않습니다.

extern constexpr int x = 10; //error LNK2005: "int const x" already defined

헤더 파일에 externconstexpr로 선언된 변수가 포함된 경우 중복 선언이 올바르게 결합되도록 __declspec(selectany)로 표시해야 합니다.

extern constexpr __declspec(selectany) int x = 10;

extern "C"extern "C++" 함수 선언

C++에서 extern을 문자열과 함께 사용하면 다른 언어의 링크 규칙이 선언자에 대해 사용 중임을 지정합니다. C 함수 및 데이터는 이전에 C 링크가 있는 것으로 선언된 경우에만 액세스할 수 있습니다. 단, 별도로 컴파일된 변환 단위로 정의되어야 합니다.

Microsoft C++는 "C" 필드에서 문자열 "C++"를 지원합니다. 모든 표준 include 파일은 extern "C" 구문을 사용하여 C++ 프로그램에 사용할 런타임 라이브러리 함수를 허용합니다.

예시

다음 예에서는 C 연결이 있는 이름을 선언하는 방법을 보여 줍니다.

// Declare printf with C linkage.
extern "C" int printf(const char *fmt, ...);

//  Cause everything in the specified
//  header files to have C linkage.
extern "C" {
    // add your #include statements here
#include <stdio.h>
}

//  Declare the two functions ShowChar
//  and GetChar with C linkage.
extern "C" {
    char ShowChar(char ch);
    char GetChar(void);
}

//  Define the two functions
//  ShowChar and GetChar with C linkage.
extern "C" char ShowChar(char ch) {
    putchar(ch);
    return ch;
}

extern "C" char GetChar(void) {
    char ch;
    ch = getchar();
    return ch;
}

// Declare a global variable, errno, with C linkage.
extern "C" int errno;

함수에 둘 이상의 연결 사양이 있는 경우에는 동의해야 합니다. C와 C++ 링크가 모두 있는 함수를 선언하는 것은 오류입니다. 뿐만 아니라 함수에 대한 두 개의 선언(하나는 연결 사양이 있고 다른 하나는 없음)이 프로그램에서 발생하는 경우 연결 사양이 있는 선언이 먼저 이루어져야 합니다. 이미 링크 사양이 있는 함수의 모든 중복 선언에는 첫 번째 선언에서 지정된 링크가 제공됩니다. 예시:

extern "C" int CFunc1();
...
int CFunc1();            // Redeclaration is benign; C linkage is
                         //  retained.

int CFunc2();
...
extern "C" int CFunc2(); // Error: not the first declaration of
                         //  CFunc2;  cannot contain linkage
                         //  specifier.

Visual Studio 2019부터 /permissive-가 지정되면 컴파일러는 extern "C" 함수 매개 변수의 선언도 일치하는지 확인합니다. extern "C"로 선언된 함수는 오버로드할 수 없습니다. Visual Studio 2019 버전 16.3부터 /Zc:externC- 옵션 뒤에 /permissive- 컴파일러 옵션을 사용하여 이 검사를 재정의할 수 있습니다.

참고 항목

키워드
변환 단위 및 링크
extern C의 스토리지 클래스 지정자
C의 식별자 동작
C의 연결