internal / external linkage

김펭귄·2025년 7월 24일

C++

목록 보기
10/20

linkage

  • 프로그램 내 여러 파일(translation unit)에 나타나는 동일한 식별자(변수, 함수 등)가 실제로 같은 것을 의미하는지, 혹은 각각 독립적인 존재인지를 결정하는 개념

internal linkage (내부 연결)

  • 식별자(변수, 함수 등)가 "정의된 파일(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; 			// 다른 객체
  }

external linkage (외부 연결)

  • 식별자가 프로그램 전체의 모든 파일(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
  • internal인 식별자는 그 파일에서만 그 식별자로 사용, 나머지는 external로 사용
// 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 사용해야함

Reference

learncpp.com
learncpp.com

profile
반갑습니다

0개의 댓글