[C++] Symbol
링크 에러 메세지에서 주로 보게되는 심볼(Symbol)이 문득 정확히 어떻게 사용되는지, 정확히 무엇을 의미하는지가 궁금해져 정리를 하게 되었습니다.
링크 에러 메세지에서 주로 보게되는 심볼(Symbol)이 문득 정확히 어떻게 사용되는지, 정확히 무엇을 의미하는지가 궁금해져 정리를 하게 되었습니다. 겉핥기로 알고 있던 심볼에 대해 더 공부하고 정리해보겠습니다.
심볼(Symbol)이란?
심볼은 컴파일러·링커가 프로그램 내부 엔티티를 식별하기 위해 생성하는 이름 정보입니다. 즉, 우리가 작성한 C++ 코드를 기계어가 이해할 수 있도록 내부적으로 사용하는 식별자입니다.
C++에서 심볼이 만들어지는 대상은 다음과 같습니다.
- 함수
- 전역 변수
- static 변수
- 클래스 멤버 함수
- 템플릿 인스턴스
- 가상 함수 테이블(vtable)
심볼은 실제 바이너리 내부에 기록되며, 링커가 여러 개의 obj 파일을 연결할 때 이 정보를 사용합니다.
C++ 심볼의 실제 형태 (Name Mangling)
C++ 함수는 오버로딩, 네임스페이스, 클래스 등 구조가 복잡해서 컴파일하면 내부적으로 이름이 변형됩니다. 이를 네임 맹글링(Name Mangling) 이라고 합니다.
예를 들어:
1 int Add(int a, int b);이 함수는 컴파일 후 다음과 같은 이름으로 변환될 수 있습니다.
1 ?Add@@YAHHH@Z
이런 형태의 이름이 바로 심볼(Symbol) 입니다.
3. 심볼과 링키지(Linkage)
심볼에는 “어디까지 보이는가?” 를 나타내는 링키지(Linkage) 개념이 붙습니다.
✔ External Linkage
다른 파일에서도 접근 가능한 심볼 (기본적인 전역 함수/전역 변수)
1
2
int gValue;
void Foo();
✔ Internal Linkage
파일 내부에서만 보이는 심볼 static 키워드로 생성됩니다.
1
static int localGlobal = 10;
✔ No Linkage
지역 변수처럼 링커가 관여하지 않는 경우, 심볼 테이블에 올라가지 않음
Undefined Symbol (미정의 심볼)
C++ 컴파일 시 선언만 있고 정의가 없는 심볼은 링커가 처리해야 합니다.
예:
1 extern int Value;
Value의 정의가 없다면 링크 단계에서 오류가 발생합니다.
1 undefined reference to `Value`
즉, 심볼은 선언 → 참조 → 정의가 일치해야 linking이 성공합니다.
Symbol Table (심볼 테이블)
컴파일러와 링커는 심볼 정보를 다음과 같이 테이블로 관리합니다
- 변수 이름, 타입, 메모리 위치
- 함수의 주소
- 템플릿 인스턴스 정보
- 가상 함수 테이블 정보
- 접근 범위 및 링크 여부
.obj 파일을 열면 심볼 테이블을 확인할 수 있습니다.
실제 심볼 테이블을 확인해보기 위해 DUMPBIN을 사용해보겠습니다.
VS2022의 터미널에서 실행했습니다.
obj 파일에서 심볼 테이블을 확인할 수 있었습니다.
왜 중요한가?
심볼은 다음 문제들의 핵심 원인/해결책이 됩니다.
- 함수 중복 정의 오류
- undefined reference 링크 오류
- static 전역과 일반 전역 변수 차이
- 템플릿 인스턴스 중복 생성 문제
- vtable 관련 링크 에러
즉, C++ 빌드 과정에서 발생하는 대부분의 문제는 결국 심볼에 대한 이해로 해결됩니다.
핵심 요약
- 심볼은 C++ 코드의 컴파일·링크 과정에서 생성되는 내부 이름
- C++은 오버로딩 때문에 Name Mangling이 적용된다.
- 심볼에는 External / Internal / No Linkage가 있다.
- 정의되지 않은 심볼은 링크 에러를 만든다.
- obj 파일 내부의 모든 정보는 Symbol Table에 기록되어 있다.


