같은 것을 의미하는지, 혹은 각각 독립적인 존재인지를 결정하는 개념식별자(변수, 함수 등)가 "정의된 파일(translation unit) 내에서만" 참조될 수 있음
같은 이름의 식별자가 다른 파일에 있으면, 서로 별개의 존재. 다른 파일에서 참조도 불가능
static, const, constexpr 사용하면 internal linkage
// foo.cpp
static int g_counter = 0; // internal linkage
static void helper() { } // internal linkage (함수도 이 파일에서만 참조)
const int g_x {5}; // internal linkage
constexpr int g_y {10}; // interal linkage
namespace A // 같은 이름의 namespace는 공유
{
int x = 0; // external
const int y = 1; // internal linkage (const)
static int z = 2; // internal linkage (static)
}
// main.cpp
static int g_counter = 0; // 또 다른, 별개 internal linkage
static void helper() { } // 또 다른, 함수. 재정의 해야함
const int g_x {1}; // 같은 이름이여도 다 다른 객체
constexpr int g_y {2};
namespace A // namespace는 이름 같으므로 공유
{
int x = 0; // error: external을 두 번 정의해서
const int y = 1; // 다른 객체
static int z = 2; // 다른 객체
}
식별자가 프로그램 전체의 모든 파일(translation unit)에서 참조될 수 있다 (진정한 의미의 global)
여러 파일에서 같은 이름이 있으면, 동일한 메모리 공간/함수 등 하나의 엔티티로 연결
global 영역 (namespace 포함)에서 선언한 변수, 함수는 기본적으로 external linkage
external linkage인 다른 파일의 식별자를 사용하려면 그 외부 변수가 선언된 똑같은 공간에서 extern 붙여서 선언
위에서 본, internal을 제외하고는 기본적으로 external
const앞에는 extern 붙이면 external로 사용 가능
// foo.cpp
int g_data = 42; // 기본적으로 external linkage
int func() { return 1; } // 함수도 default로 external
extern const int g_MAX = 100; // external linkage 부여
namespace foo {
int globalVar = 10;
}
// main.cpp
// extern 붙여 foo파일의 식별자들 참조하여 사용
extern int g_data; // 같은 global_data를 참조 (같은 전역 공간에서 선언)
int func(); // 함수는 prototype 선언으로 사용
extern const int g_MAX;
namespace foo {
extern int globalVar; // 동일하게 namespace에서 참조 선언
}
int main() {
std::cout << g_data; // 42
std::cout << func(); // 1
std::cout << g_MAX; // 100
std::cout << foo::globalVar; // 10
}
// foo.hpp
// 헤더파일에서 전역변수를 external로 "선언" 및 다른 파일에서 사용하도록 함
#pragma once
int func(); // 함수를 헤더에서 선언하듯이
extern int g_data; // 전역변수도 선언만
extern const int g_MAX; // const는 여기서 extern 붙여 external로
namespace foo {
extern int globalVar; // const도 똑같이 가능
}
// foo.cpp
// cpp파일에서 정의를 한다
int func() { return 1; }
int g_data = 42;
const int g_MAX = 100; // 헤더에서 extern 붙였으므로 external
namespace foo {
int globalVar = 10;
}
// main.cpp
// 헤더파일을 include했기에 다른 파일에서는 그냥 사용 가능
#include <iostream>
#include "foo.hpp"
int main() {
std::cout << func(); // 1
std::cout << g_data; // 42
std::cout << g_MAX; // 100
std::cout << foo::globalVar; // 10
}
extern으로 참조하려고 할 시 에러 발생// foo.cpp
static int g_x{10}; // internal linkage
// main.cpp
extern int g_x; // link error
// a.cpp
int g_x {10}; // 다른 파일들에서 사용 가능한 전역변수
// b.cpp
static int g_x {5}; // 이 파일은 이 g_x(5)를 사용
extern int g_x; // error: x 2번 정의하였다고 에러 (a.cpp의 x 사용불가)
// main.cpp
extern int g_x; // a.cpp의 x를 사용 (10)
constexpr을 external로 사용하려면 inline 사용해야함