C++ Name Mangling
// main.cpp
#include "square.h"
int main()
{
// Error - square를 찾을 수 없음
square(3);
}
// square.h
#pragma once
int square(int a);
// square.c
int square(int a)
{
return a * a;
}
왜 그럴까?
- 언어 옵션 중 다음 두 가지가 있다
/Tc
: 주어진 소스를 C언어 문법으로 컴파일/Tp
: 주어진 소스를 C++언어 문법으로 컴파일
# Example
$ cl /Tc squre.c /c /FAs /Faasm1.asm # /Faasm1.asm : 어셈블리 파일이름을 asm1.asm으로 만들어달라
$ cl /Tp squre.c /c /FAs /Faasm2.asm
이렇게해서 어셈블리파일을 보면
- 함수의 이름이 다음과 같다
- C :
_squre
- C++ :
?squre@@YAHH@Z
- C++은 함수 오버로딩 문법으로 같은 함수명의 함수가 여러개 나올 수 있음. 따라서 C++에서는 매개변수 + 함수명으로 해서 어셈블리의 함수명이 이상하게 나온다 -> 이걸 Name Mangling 이라한다
- C :
- 이제 위 코드의 문제를 알 수 있는데
main.cpp
에서squre.c
를 호출하면 함수명의 규칙이 같지않기에 링크에러가 발생!
해결해보자
// square.h
#pragma once
// C로 구현되었음을 알려준다
extern "C" int square(int a);
- 그럼 main.c로 변경하면?? -> 또 에러가 발생
extern "C"
를 c컴파일러가 모른다extern "C"
자체가 C++문법이다
해결해보자
// square.h
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
int square(int a);
#ifdef __cpluscplus
}
#endif