• 1.8.1 링킹 에러
  • 1.8.2 중복 정의
  • 1.8.3 헤더 가드(Header Guards)

1.8.1 링킹 에러

 

Linking Error

프로그램을 만들다 보면 LNK2019, LNK1120이라는 링킹 에러를 만나는 경우가 종종 생긴다. 위와 같은 에러가 생기는 이유는 특정 함수에 대하여 선언은 존재하지만 정의가 존재하지 않는 경우이다. 

 

add function header

위처럼 add 함수에 대한 선언을 헤더 파일로 작성하고서 include를 통해 main 함수가 작성된 코드에서 add 함수를 사용했다면 전방 선언이 된 효과를 가지게 된다. 선언이 되어 있으므로 컴파일러는 통과를 시키고 빌드가 이루어지는데, 결국 해당 함수의 정의가 담긴 cpp 파일이 없다면 함수 호출 뒤에 어떤 연산을 해야 할지 모르는 상황이 발생하면서 링킹 에러가 생긴다. 따라서 링킹 에러가 생긴다면 혹시나 정의를 빼먹은 함수가 없는지 확인해보자!


1.8.2 중복 정의

 

위와는 다르게 과도한 정의로 인한 에러가 생기는 경우가 있다.

function already has a body

이처럼 C2084 에러가 잡히면 Description 의미 그대로 이미 중복 선언이 된 경우이다. 일반적으로 많은 함수를 선언과 정의를 해서 헤더 파일로 가지고 있다면 여기저기서 include를 통해 함수를 재사용하고 있을 것이다. 다음의 예시를 보자.

 

add header
dosomething header

add 함수가 있는 헤더 파일을 만들고 add 함수를 끌어다 쓰는 doSomething 함수를 만들어 다른 헤더 파일에 만들었다.

 

main 함수

그리고 main 함수가 담긴 cpp 파일이 위처럼 작성되어 있다. 여기서 #include 전처리기가 작동하는 방식을 이해하면 왜 중복 정의인지 알 수가 있는데, #include 전처리기는 해당 파일을 복사해서 가지고 오는 것처럼 작동한다. 따라서 위의 코드는 아래와 같은 상황이 벌어진다.

 

add 중복


1.8.3 헤더 가드(Header Guards)

 

아마 헤더 파일을 만드는 순간 #pragma once라는 전처리기를 보았을 것이다. 해당 전처리기는 이미 한번 정의된 함수라면 다시 정의하지 않도록 해주는 전처리기로 프로그램이 커질수록 해당 전처리기의 도움을 많이 받는다. 같은 방식으로 동작하는 것이 아래의 코드가 되겠다.

 

#ifndef  MY_ADD
#define  MY_ADD

int add(int a, int b)
{
	return a + b;
}

#endif // ! MY_ADD

 

다음과 같이 코드가 작성 되어 있다면 가장 앞에 #pragma once 전처리기를 둔 것과 같은 효과를 지닌다. #ifndef MY_ADD를 통해 만약 MY_ADD가 정의되어 있지 않다면 #endif 바로 위까지 코드를 읽어드리는 것이다. 이런 경우 #define MY_ADD가 최상단에서 정의가 되고 add 함수를 정의하기 때문에 추후 해당 헤더 파일을 다시 include하더라도 MY_ADD가 정의되어 있기 때문에 다시 add 함수를 정의하는 불상사는 발생하지 않는다.

+ Recent posts