C/C++ 다형성과 extern "C"

Posted by : on

Category :


C와 C++에서 사용되고 있는 함수의 형식이 다르다

C++ 프로그램에서는 함수의 다형성이 지원되고 있다. 반환타입과 함수의 이름이 같더라도, 함수의 인자 형식이 다르면 같은 이름을 가진 함수를 선언할 수 있다.

예시는 다음과 같다.

double sum(double x, double y);
int sum(int x, int y);
long long sum(long long x, long long y);

같은 행동을 하는 프로그램을 만들어야 하지만, 함수의 이름을 sum_d, sum_i, sum_l로 짓기에는 너무 귀찮아진다.

이를 해결하기 위해 C++에서는 같은 이름을 가진 함수를 선언할 수 있다.

선언된 함수는 함수 이름의 길이, 인자의 종류 등이 추가되어 함수의 이름이 내부적으로 결정된다.

예를 들어, (int, int, char) 형태의 인자를 가지고 있는 printSum 이라는 함수는 다음과 같은 형식으로 내부 함수 이름이 결정되게 된다.

_Z8printSumiic
//_Z(함수 글자수)(함수이름)(인자들 순서대로) 로 오는 듯 하다.

컴파일러에서 어셈블리어로 컴파일하는 과정 이후, 링킹 이전에 이러한 형태를 볼 수 있으며, C++로 만들어진 프로그램을 뜯어보면 이러한 형태의 함수 이름을 사용하고 있는 것을 알 수 있다.

이러한 형태는 다음 사이트에서 쉽게 확인할 수 있다.

어셈블리어 프로그래밍을 하며 C++프로그램과 링킹 할 때, 함수명을 다음과 같이 정해주면 C++프로그램에서 extern “C”를 적용하지 않아도 컴파일러가 인식해서 제대로 묶어주게 된다.


C++코드 내부의 함수 이름을 알아내고 싶으면 다음 명령어를 사용해 어셈블리 코드를 알아낼 수 있다. 내부에서 작성한 함수 이름으로 검색하면 찾을 수 있다.

g++ -S (CPP파일)
# 참조나 외의 것들이 맞지 않아도, 문법만 맞으면 제대로 컴파일된다.
# 여러 파일에 대해 한 어셈블리 소스를 만들수도 있고, 여러 어셈블리 소스를 한 출파일로 만들수도 있다.

다음과 같이 하면 어셈블리 코드 파일이 나오게 되는데, 이를 as (어셈블리 소스 파일 이름) 을 통해 컴파일 할 수 있다.

이후 g++ (as로 나온 파일 이름들) 을 통해서 링킹할 수 있으며,

혹은 g++ (cpp 소스코드) (as로 나온 파일 이름들)을 통해서 프로그램으로 링킹할 수 있다. (내부적으로 링킹해준다)


Useful Links