- extern "C"의 의미
#ifdef __cplusplus
extern "C" {
#endif
..... .....
..... .....
#ifdef __cplusplus
}
#endif
- extern C : C++에서만 사용되는 Identifier로, 중괄호 안에 정의된 function 또는 header file에 관해서는 mangling하지 말라는 뜻
- 즉 C언어의 호출 규칙을 사용하도록 함
- 보통 C에서 선언한 Function이나 Global Variable을 C++에서 사용할 때 선언
- extern은 Link의 규칙을 정하는 keyword
- Name Mangling
- C++에서 사용되는 개념으로, C++ compiler 단계에서 이미 선언된 function 혹은 variable의 이름에 function의 arguments와 관련된 일정한 규칙을 가지고 변형하는 것
- 이름을 크게 바꾸어 mangilng이라는 단어를 사용함
- Mangling : 어떤 대상을 꼬거나 여러 조각으로 찢어 원래 형태와 달라지게 하는 것
- Ex) func_example -> _Z10func_examplei
- 이를 통해 C++에서는 똑같은 이름의 function을 parameter에 따라 구분지을 수 있다
- 이러한 C++의 기능을 Function Overloading이라 한다
- Compiler, Linker
- Compiler : 고급 언어를 기계어로 번역하여 Object File을 생성
- 각각의 Source Code에 별도로 동작하여 별개의 Object File을 생성
- Linker : Symbol을 해석하고 주소를 할당하여 Object File을 Executable File / Library 와 결합
- 즉 Compile 이후, 생성된 여러 Object File들을 하나의 File로 합침
- 그 과정에서 함수의 호출 부분과 정의 부분을 연결(Link)
- extern "C"는 이 'Link' 과정에서 Name Mangling으로 인해 발생하는 문제를 해결하고자 사용됨
- extern "C" 사용 이유
- C++과 달리 C언어에서는 Function Overloading을 지원하지 않으므로, linker가 function을 이름으로만 구분한다
- 그런데 C언어로 작성된 source code를 include 할 경우, C언어는 다형성을 지원하지 않으므로 mangling된 function의 원형을 알 수가 없어 Link 과정에서 Error가 발생한다
- 예를 들어, 아래와 같이 C언어로 정의된 함수를 포함한 Header Filer을 C++에서 include 할 경우,
// example.h (C)
#ifndef EXAMPLE_H
#define EXAMPLE_H
void c_function(int x); // Declaration of c_function
#endif // EXAMPLE_H
// example.c
#include "example.h"
void c_function(int x) {
/*
Definition of c_function
*/
}
// main.cpp
#include "example.h"
int main() {
c_function(10); // g++ compiler compiles it to the mangled name of c_function
return 0;
}
- C source code : 함수의 정의 부분
gcc -c example.c -o example.o
- C compiler(gcc)가 c_function의 정의 부분을 포함한 example.c를 compile
- Name Mangling이 되지 않은 'c_function'의 이름을 포함한 object file 'example.o'을 생성
- C++ source code : 함수의 호출 부분
g++ -c main.cpp -o main.o
- C++ compiler(g++)가 main.cpp를 compile
- Name Mangling을 통해 'c_function'의 호출 부분을 '_Z10func_examplei'와 같은 이름으로 변형한 object file 'main.o' 생성
- Linking : 위 둘을 결합
g++ main.o example.o -o my_program
- Linker가 'main.o'와 'example.o'를 결합
- Linker가 'main.o' 내의 'c_function' 호출 부분을 'example.o' 내의 'c_function'의 정의 부분과 대응시키려 함
- 구체적으로는 Client C Linker가 함수의 이름 ' c_function'를 통해 main.o로 link를 하려 함
- 이 때, 각 object file 내의 함수의 이름은 아래와 같이 서로 다르므로 linker가 둘을 대응시킬 수 없음
- 'main.o' 의 함수 호출 부분 : '_Z10c_functioni'
- example.o의 함수 정의 부분 : 'c_function'
- extern "C" 사용
// main.cpp
extern "C" {
#include "example.h"
}
int main() {
c_function(10);
return 0;
}
- 이를 해결하기 위해 extern "C"를 사용하여 C++에서의 function의 이름이 C의 linkage를 갖게 한다
- 즉 Name Mangling을 하지 않도록 하여 client C 코드가 C와 호환되는, 함수의 선언만을 갖고 있는 Header File 사용을 통해 C++의 function에 link할 수 있도록 한다
- 구체적으로는 Linkage에 사용되는 Function의 이름에 parameter 정보를 추가하지 않는다
* C++ 파일에서 C header file (ex) stdio.h)를 사용할 수 있는 이유도 header file에 extern C 처리가 되어있어 C++ source file에서도 mangilng 작업이 진행되지 않게 했기 때문
- # ifdef __cplusplus 사용 이유
- # ifdef _cplusplus : extern "C"는 C++에서만 정의되는 Identifier이므로, C에서 사용할 시 Error가 발생한다
- 이를 방지하기 위해 코드의 Complier를 위 구문으로 확인한 후 C++일때만 extern "C"를 사용하게 한다
- 즉 C++ 코드에서 C Headrer file을 사용할 수 있게 한다
- __cplusplus는 해당 코드의 Compiler가 C++용임을 의미
// main.cpp
# ifdef __cplusplus
extern "C" {
# endif
#include "example.h"
# ifdef __cplusplus
}
# endif
int main() {
c_function(10);
return 0;
}
- g++ --std=c++14 의 경우 _cpluscplus가 201402L
- C++ 표준에 따라 default 값이 달라진다
- 정리
- C Header file을 C++ 코드에서 사용할 경우, C Compiler를 통해 생성된 Object File과 C++ Compiler를 통해 생성된 Object File을 Linker를 통해 결합하게 된다
- C compiler의 경우 compile 시, Object File에 c_fuction 함수의 이름 자체로의 Symbol을 생성한다
- 그런데, C++ Compiler의 경우 Object File에 c_function 함수의 이름을 ' _Z10c_functioni' 와 같은 이름으로 mangling한 Symbol을 생성한다
- 이로 인해, Compile이후 실제로 호출된 함수를 연결하는 Link 과정에서 Linker는 C++ Object file 내의 ' _Z10c_functioni'라는 symbol로 C Object File 내에서 함수의 정의 부분을 찾는데, C compiler는 이 함수를 이름 그대로 갖고 있으므로, link 오류가 발생하게 된다
- Linker는 Object file 내의 symbol을 기준으로 함수의 선언과 정의를 연결한다
참고 자료 :
https://stackoverflow.com/questions/1041866/what-is-the-effect-of-extern-c-in-c
What is the effect of extern "C" in C++?
What exactly does putting extern "C" into C++ code do? For example: extern "C" { void foo(); }
stackoverflow.com
https://5kyc1ad.tistory.com/343
[C/C++] extern "C"와 네임 맹글링
최근 개인적으로 리눅스 환경에서 C/C++을 혼합해서 쓸 일이 생겼는데, 그때 extern "C"를 사용하면서 알게 된 점들을 작성해 보려고 합니다. 해당 프로젝트는 'https://github.com/skyclad0x7b7/MiniHook' 요놈
5kyc1ad.tistory.com
https://noel-embedded.tistory.com/1078
extern "C" 의미
extern "C" 의미는 안에 정의된 함수 혹은 헤더파일에 관해서는 맹글링하지 말라는 의미다. 맹글링은 C++에서 사용되는 용어로, C++ 컴파일러 단계에서 함수 혹은 변수이름을 기존과 크게 다르게 바
noel-embedded.tistory.com
C++/extern "C" 를 쓰는 이유
들어가기 앞서, = 네임 맹글링(Name Mangling) = 코드에서 선언한 함수나 변수의 이름을 컴파일러가 컴파일 단계에서 일정한 규칙을 가지고 변형하는 것. 맹글링을 영어 사전에서 찾아보면 난도질 하
hyacinth.byus.net
https://noel-embedded.tistory.com/1139
__cplusplus 매크로 의미
https://noel-embedded.tistory.com/1078 해당 글에서 extern "C"의 의미를 대략 파악했다. 결국에는 c 소스를 cpp에서 가져다 쓸 때 맹글링 작업을 막는 것이다 stdlib.h 안에 내용인데 ifdef __cplusplus가 정의되어
noel-embedded.tistory.com
C++ 상에서 발생하는 name mangling 에 관한 내용
이 글에서 다뤄보고자 하는 내용은 2가지 입니다. 하나는 name mangling 이고 다른 하나는 extern "C" 입니다. 이 두가지는 c와 c++의 호환성과 관련된 부분이기도 하고 라이브러리를 사용하다보면 가끔
spikez.tistory.com
'Study_C, C++' 카테고리의 다른 글
Visual Studio에서의 <bits/stdc++.h> 사용법 (1) | 2023.08.29 |
---|