extern, static은 c++ 빌드 프로세스에서 핵심적인 키워드이다.
두 키워드는 모두 링킹 linkage 프로세스와 관련이 되어 있다.
extern: 바깥쪽에서 링크를 찾아라.
static: 바깥쪽이 아닌 안쪽으로만 링크를 열어라.
*c++에서는 이렇게 빌드 프로세스에서 사용되는 static 말고도 static 메모리를 사용하라는 static 키워드가 존재하니 헷갈리지 말자.
*참고
cppreference의 static extern 의 linkage 파트 참고할 것. https://en.cppreference.com/w/cpp/language/storage_duration
예제1
위의 경우, int a 를 두 번 선언되어 컴파일은 되었으나 링크가 되지 않았기에 에러가 뜨는 것이다.
그림으로 나타내 보면,
main.cpp와 foo.cpp를 컴파일 하게 되면 object 파일까지 문제없이 a에 대한 정보를 갖고 있지만,
마지막으로 linkage process를 통해서 하나의 실행 파일을 만들어 줄 때 a가 중복되는 것을 보고
어떤 a를 사용해야 할지 컴파일러가 모르기 때문에 이런 에러가 발생하는 것이다.
extern 사용
a의 앞에 extern 을 붙이고 초기화 해주지 않고 컴파일 해 보면 a = 100 으로 컴파일 되는 것을 확인할 수 있다.
100은 지금 foo.cpp 파일에 정의되어 있다.
그림으로 보면
extern a 의 의미는, 'a의 정의는 바깥쪽 어딘가에 있다' 는 의미이다.
그렇기 때문에 foo.cpp 에 정의된 a = 100 을 그대로 가져와서 컴파일 결과값으로 쓰게 되는 것이다.
static 사용
빌드는 정상적으로 되고 결과값은 0이 나온다.
static은 object 파일을 만들 때 a라는 변수를 바깥쪽에서 찾을 수 없게 만드는 기능을 해 준다.
즉 하나의 translation unit, object 파일 안에서만 접근이 가능하도록 만들어주는 키워드이다.
링커가 foo.o파일에서는 a에 접근할 수가 없기 때문에 main에 있는 a를 사용하게 된다.
따라서 컴파일 결과값이 0이 되는 것이다.
Function의 경우
void foo 앞에 extern 을 사용하게 되면 앞서 변수에 붙였던 것과 마찬가지로 외부에서 그 정의를 찾아서 foo라는 동일한 결과가 나온다.
함수에 대해서는 default 값으로 extern 이 붙어 있는 것.
static void bar();
결론적으로, 함수 또는 변수가 하나의 object file 또는 translation unit 바깥으로 링크를 주지 않는다는 확신이 있다면,
static 키워드를 붙여주어 더 안전한 빌드 프로세스를 가져갈 수가 있게 되는 것이다.
이런 경우에 bye() 함수를 private 멤버로 정의하는 것 보다는, static을 붙여준 free function으로 만들어 주면 bye() 함수는 cat.o 오브젝트 파일에서만 접근 가능한 함수가 된다.
이처럼 함수가 오브젝트와 직접적인 관련이 없다는 생각이 들면 static을 붙여준 free function으로 만들어 주는 것이 일반적인 방법이다.
extern "C" 키워드
C에서는 function overloading 기능(c++에서 존재하는)이 없다. 따라서 당연하게도 name mangling 기능도 없다.
extern "C" 는 function name을 mangling 하지 않도록 만들어준다.
즉 C 인터페이스를 가진 binary를 제공할 때 name magling 기능을 모두 없애주어야 하는데,
이 때 사용하는 키워드가 바로 extern "C" 인 것이다.
헤더 파일에서 extern "C" 를 선언해주고 사용하면 된다.
'모던C++ > 컴파일 프로세스 Compile Process' 카테고리의 다른 글
4. Static Library (0) | 2022.07.13 |
---|---|
2. PreProcessor 프리프로세서 - 전처리기 (0) | 2022.07.12 |
1. 헤더 파일의 의미, 사용법 (0) | 2022.07.11 |
0. C++ 빌드 프로세스, 컴파일 프로세스 (0) | 2022.07.11 |