2.6 Forward declarations and definitions

주홍영·2022년 3월 11일
0

Learncpp.com

목록 보기
30/199

https://www.learncpp.com/cpp-tutorial/forward-declarations/

함수나 변수같은 것을 사용할 때 정의나 선언에 있어서
항사 사용하기 전에 정의, 선언을 해줘야
컴파일할 수 있다는 내용
컴파일러는 sequentially 하게 code를 컴파일 하기 때문에 먼저 선언을 해줘야 한다

근대 만약 main 함수 이전에 A, B의 함수가 존재하는데
A, B가 서로를 사용한다면 어떤 함수가 먼저 오더라도 앞서 말한 컴파일러의 특성 때문에
컴파일이 성공적으로 이뤄질 수 없다
이러한 경우에 Forward declaration이 유용하다

Forward declaration

실패 예시)

void A()
{
	B();
}

void B()
{
	A();
}

int main()
{
	A();
}

위의 경우 앞서말한 컴파일러의 특성 때문에 컴파일이 되지 않는다

#include <iostream>

int add(int x, int y); // forward declaration of add() (using a function prototype)

int main()
{
    std::cout << "The sum of 3 and 4 is: " << add(3, 4) << '\n'; // this works because we forward declared add() above
    return 0;
}

int add(int x, int y) // even though the body of add() isn't defined until here
{
    return x + y;
}

따라서 위와 같이 forawrd declaration을 이용해 함수의 형태를 선언해주고 나중에 정의를 해서
컴파일이 되도록 할 수 있다.

function prototype은 다음과 같이 parameter의 type만 기입해도 된다

int add(int, int); 

Forgetting the function body

만약 forward declaration을 해주고 body를 정의 하는 것을 깜빡했을 경우 어떻게 되나?

이러한 경우에는 함수가 불리지 않았을 경우에는 컴파일에 문제가 없으나
함수가 call 되었을 경우 body가 존재하지 않으므로 compile은 되고 linker가 function call을 해결할 수 없다고 complain을 한다고 한다

따라서 다음과 같은 message를 받아보게 될 것이다

Compiling...
add.cpp
Linking...
add.obj : error LNK2001: unresolved external symbol "int __cdecl add(int,int)"(?add@@YAHHH@Z)
add.exe : fatal error LNK1120: 1 unresolved externals

위에서 볼 수 있다시피 linking에서 error가 발생한다

Quiz

Q1 What is a function prototype?

A function prototype is a declaration statement that includes a function’s name, return type, and parameters. It does not include the function body.

Compile error vs Linking error

Case #1

#include <iostream>
int add(int x, int y);

int main()
{
    std::cout << "3 + 4 + 5 = " << add(3, 4, 5) << '\n';
    return 0;
}

int add(int x, int y, int z)
{
    return x + y + z;
}

Case #2

#include <iostream>
int add(int x, int y);

int main()
{
    std::cout << "3 + 4 + 5 = " << add(3, 4) << '\n';
    return 0;
}

int add(int x, int y, int z)
{
    return x + y + z;
}

1번 케이스에서는 add의 형태와 맞는 함수가 없으므로 아예 컴파일부터 되지 않는다
반면 2번 케이스는 forward declaration의 function prototype이 add와 일치하므로
compile은 되지만 linker가 형태가 일치하는 definition을 찾을 수 없으므로
linking error가 발생한다

profile
청룡동거주민

0개의 댓글