extern "C"와 네임 맹글링

 

오픈소스같은 곳에 보면 extern "C"라는 문법이 종종 보이는데 처음에 보면 이게 뭐하는거지 C로 컴파일 해준다는건가? 아니면 C문법으로 바꾸어 쓰라는건가? 라고 의문이 생길겁니다. 이번엔 extern "C"가 뭐하는 녀석인지 알아봅시다. 


네임 맹글링

 

extern "C"를 알아보기 전에 네임 맹글링에 대해서 먼저 알아봅시다.

 

컴파일러들은 컴파일을 할때 다른곳에서 접근할수 있도록 심볼을 만드는 작업을 합니다. 
여기서 함수를 심볼로 만들때 심볼이름을 함수이름 그대로 생성하는 C컴파일러와 달리 C++컴파일러들은 각각 정해진 규칙에 따라 심볼이름을 변경하여 생성합니다. 
이러한 작업을 네임 맹글링이라고 하며 C와 달리 C++에서는 함수 오버로딩 같은 다형성을 지원할 수 있는 이유이기도 합니다. 

 

그러면 이제 실제로 네임 맹글링이 되고있는지 확인해봅시다.

 

test_c.c

/* C 코드 */
#include <stdio.h> 

void test()
{
	printf("extern c test!!\n");
}

int main()
{
	test();
	return 0;
}

 

test_cpp.cpp

/* C++ 코드 */
#include <iostream>
using std::cout;
using std::endl;

void test()
{
	cout << "extern c test!!" << endl;
}

int main()
{
	test();
	return 0;
}

 

컴파일

# C 컴파일 #
gcc -c test_c.c
gcc -o test_c test_c.o

# C++ 컴파일 #
g++ -c test_cpp.cpp
g++ -o test_cpp test_cpp.o

 

결과

 

readelf 명령어를 사용하여 확인해보면 실제로 C로 컴파일한 파일은 test 라는 이름으로 심볼이 생성되었고 C++로 컴파일한 파일은 _Z4testv 라는 이름으로 심볼이 생성된걸 확인할 수 있습니다.


extern "C"

 

자 그러면 이미 눈치채신 분들도 있을겁니다. 

extern "C"는 네임 맹글링을 사용하지 않는다. 라는 의미로 extern "C"를 선언하면 그 안에 모든 코드들은 네임 맹글링을 하지 않습니다.

 

그럼 실제로 네임 맹글링 작업을 안하는지 알아봅시다.

 

test_cpp_extern_c.cpp

/* C++ 코드 */
#include <iostream>
using std::cout;
using std::endl;

extern "C" 
{
	void test()
	{
		cout << "extern c test!!" << endl;
	}
}

int main()
{
	test();
	return 0;
}

 

컴파일

# C++ extern "C" 컴파일 # 
g++ -c test_cpp_extern_c.cpp
g++ -o test_cpp_extern_c.o

 

결과

 

extern "C"를 적용안한 파일에서는 _Z4testv 로 심볼이 생성되었고 extern "C"를 적용한 파일에는 C코드와 마찬가지로 test라는 이름으로 심볼이 생성된걸 확인할 수 있습니다.


마무리

 

지금까지 extern "C"와 네임 맹글링에 대해서 알아보았습니다.

잘못된 점이 있거나 궁금한 점이 있다면 언제든지 문의해주시기 바랍니다!

728x90
반응형

+ Recent posts