[C/C++]네임 맹글링(Name mangling)

2022. 4. 9. 00:46Programming language/C, C++

    목차

이 글은 이전에 운영하던 깃 블로그에서 옮겨온 글입니다.

 

서론

직역하면 "이름 짓이기기". 음... 이게 뭐길래 어감이 영 좋지 않습니다. 오늘은 제가 외부 라이브러리나 브리지 작업을 할 때 주로 겪었던 Name mangling에 관하여 글을 써보려 합니다.


Name Mangling

Name Mangling은 컴파일러가 자기 마음대로 변수나 함수의 이름을 변경하는 것을 의미합니다.

함수 오버 로딩을 알고 있나요? 함수 이름이 같고 리턴 값 타입이나 매계 인자가 다른 경우에도 하나의 이름으로 사용할 수 있게 해 주는 C++의 기능입니다. 여담으로 Name Decoration이라고 부르기도 합니다.


예를 들어 보겠습니다. 아래는 매계인자로 받은 값을 + 해주는 함수를 작성한 코드입니다.

int Add(int a, int b) { return a + b; }

그런데, 정수는 위처럼 작성한다 하고… 실수끼리나 정수 + 실수는? 각각 함수 이름을 다르게 해서 작성하면? 물론 됩니다. 하지만 가독성과 유지보수랑은 작별인사를 하셔야 합니다. 그냥 Add라는 함수로 리턴 값과 매계 인자 타입만 바꿔주면 간단할 테니 해보도록 하겠습니다.

float Add(float a, float) { return a + b; }

float Add(int a, float b) { return a + b; }

일단 코드는 작성해서 프로그래머는 압니다. 다르게 보이니까요. 저것이 오버 로딩이라는 개념입니다. 하지만 컴파일러는 어떻게 구분할까요? 컴파일러는 컴파일 시 Add함수를 서로 다른 이름으로 번역하여 구분합니다다. 즉, Name Mangling을 해주게 됩니다. 의도한 이름이... 안 나오는 거죠.

//컴파일된 Name mangling 결과
int Add(int a, int b) { return a + b; } => Addii

float Add(float a, float) { return a + b; } => Addff

float Add(int a, float b) { return a + b; } => Addif …

 

위처럼… 심지어 Namming 방식은 컴파일러마다 다르다기 까지 합니다.
어쨌든, 이렇게 임의로 이름을 붙여줘 오버 로딩을 가능하게 해 줍니다. 그렇다면 저는 왜 이것이 문제라고 했을까요?


Name Mangling 피하기

외부 모듈이 C 기반일 경우 C++로 작성된 모듈에 접근이 가능할까? 생각해보면, 아니 불가능할 것이라는 결론이 나옵니다. 그 이유는 아래와 같습니다.

C는 C++의 Name Mangling 규칙을 모른다! 둘은 엄연히, 다른 언어니까!

같은 C++ 언어라도 컴파일러가 다를 경우 C++모듈 사이에서도 접근이 안됩니다. 그럼 방법이 없는가?
물론 방법은 있다. Name Mangling을 피하면 됩니다.

 

아니 이게 무슨 말이지? 예전에 [C/C++] C++의 키워드 몇 가지라 에서 extern이라는 키워드를 소개한 적 있습니다.

이 키워드로 선언된 전역 변수는 이미 다른 파일에 선언되어있는 변수라는 것을 알려주는 녀석입니다.
"DLL 같은 라이브러리를 만들 때 주로 사용했던 것 같습니다."

Plugin을 만들 때 extern함수로 선언해야 했어야 했습니다. extern은 기본 적은로 extern 'C++'이라는 뜻입니다.

 

기본적으 외부 함수 라도 C++로 작성되었으며 Mangling을 진행하는데, 외부에서는 코드로 작성된 함수 이름과 바이너리(lib파일)로 뽑혀 읽는 함수의 이름을 다르게 읽을 것이다. 결국 어떤 건지 모른니 말이죠.


즉, 명시적으로 extern "C" 키워드를 이용하여 외부 함수로 작성하여 Name Mangling을 진행하지 않고 함수 이름을 그대로 읽어해 주는 것이 공용 라이브러리 등을 만들 때 필수적이라 할 수 있습니다. 이를 안 해주면 만든 사람에게 욕을…

반응형
LIST