[원티드 포텐업] 링커 동작 방식
#이 들어가면 전처리에서 코드 뭉치로 변환
전처리: 컴파일하기 위한 준비
컴파일: cpp파일만 체크해서 구문 확인
링커: 파일들을 탐색해서 연결 시켜준다. 목표: 빠르게 X 문제 없이 O
링킹(Linking)
컴파일한 중간 파일(obj)들을 서로 연결하는 과정
1. 각종 심볼(symbol, 변수 등) 및 함수가 어디에 있는지 확인하고 서로 연결하는 과정
2. cpp 파일이 obj 파일로 컴파일되면 cpu가 읽을 수 있는 translation unit으로 변환되는데 obj 파일 각각은 서로 연결 고리(관계)가 없기 때문에 다른 파일에 대한 정보를 알지 못함
3. 이들을 서로 연결해주는 과정이 링킹
이렇게
C++은 [컴파일 + 링크] 단계를 거치고,
그 과정에서 발생하는 오류의 이름은 이렇게 된다.
C0000 -> 컴파일 오류 LINK0000 -> 링크 오류 |
main.cpp 하나만 만들어보자
#include <iostream>
void Log(const char* message)
{
std::cout << message << std::endl;
}
int Multiply(int a, int b)
{
Log("Multiply");
return a * b;
}
이 상태에서 ctrl + F7을 사용해서 컴파일만 하면 아무 문제가 없다.
하지만 빌드를 하면 main 함수를 찾을 수 없다는 오류가 생긴다.
LNK0000 -> 링크오류
이렇게 main만 추가해주면 링크오류는 사라지고 정상작동된다.
#include <iostream>
void Log(const char* message)
{
std::cout << message << std::endl;
}
int Multiply(int a, int b)
{
Log("Multiply");
return a * b;
}
int main()
{
std::cout << Multiply(5, 8) << std::endl;
std::cin.get();
}
그럼 이제 Log.cpp를 따로 만들어보자
Log.cpp
#include <iostream>
void Log(const char* message)
{
std::cout << message << std::endl;
}
main.cpp
#include <iostream>
int Multiply(int a, int b)
{
Log("Multiply");
return a * b;
}
int main()
{
std::cout << Multiply(5, 8) << std::endl;
std::cin.get();
}
이렇게해서 main.cpp만 컴파일 오류가 발생한다. Log가 뭔데
그럼 Log만 알려줘
#include <iostream>
void Log(const char* message);
int Multiply(int a, int b)
{
Log("Multiply");
return a * b;
}
int main()
{
std::cout << Multiply(5, 8) << std::endl;
std::cin.get();
}
이렇게 수정해주면 빌드가 가능해진다.
그렇다면 이렇게 선언하면 어떻게 될까?
Log.h
#pragma once
#include <iostream>
void Log(const char* message)
{
std::cout << message << std::endl;
}
Log.cpp
#include <iostream>
#include "Log.h"
void InitLog()
{
Log("Initialize Log");
}
main.cpp
#include <iostream>
#include "Log.h"
int Multiply(int a, int b)
{
Log("Multiply");
return a * b;
}
int main()
{
std::cout << Multiply(5, 8) << std::endl;
std::cin.get();
}
정답:
Link오류가 난다.
log.cpp에 #include "Log.h"가 void Log()로 바뀌고,
main.cpp 에 있는 #include "Log.h"도 void Log()로 바뀐다.
그럼 Log가 두번 선언되니까 Link Error가 발생하는 것이다.
기억해야 될 것:
1.
맨날 class를 .cpp, .h로 자동으로 나눠서 사용하다보니
놓치던게 많았다.
그래서 #include < .h> 해야 서로 소통이 되는 건 줄 알았지만,
헤더를 선언하지 않아도 linker가 이리저리 뒤져보다가 함수 이름이 같네? 링크에러를 발생시킨다.