0. 개요

프로그래밍에서 선언(declaration)과 정의(definition)는 명백히 다른 역할을 하지만 혼동하여 사용하기 쉽습니다.


선언과 정의의 가장 큰 차이는 "메모리를 할당하는가" 입니다.

메모리를 할당하지 않고, 대상의 이름만 알려준다면 선언이고 대상의 메모리가 할당된다면 그것은 정의입니다.


1
2
3
4
5
void main()
{
    int a;         // 변수의 선언과 동시에 정의
    int b = 10;  // 마찬가지..
}
cs


위의 예는 선언이기도 하며, 정의기도 한 경우입니다. 

이처럼 변수는 선언과 동시에 정의되는 경우가 많으며 '변수를 선언한다', '변수를 정의한다' 와 같이 크게 선언과 정의를 구분지어 얘기하지 않습니다.

혼동하기 쉬운 예로 typedef는 사용자 정의 타입이라고 불리지만 실제로 메모리 영역상에 올리지는 않기 때문에 정의라고 볼 수 없습니다.


그렇다면, 선언과 정의는 무엇이며 각자의 특징에 대해 좀 더 자세히 알아보겠습니다.




1. 선언

컴파일러가 참조할 식별자(identifier)와 이름을 알립니다.

여기서 식별자란 변수의 타입과 함수의 인수목록을 뜻하며 이름은 변수, 함수, 클래스의 이름, 네임스페이스를 뜻합니다.


선언은 메모리 영역 상에 올리지 않기 때문에 중복되어도 문제가 되지 않으며 두 번 이상 할 수 있습니다.

다음은 변수와 함수의 선언입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
extern int a;             // 전역변수의 선언
 
int add(int a, int b);    // 함수의 선언(함수의 본문이 없습니다.)
 
class ClassID;            // 클래스의 선언
 
class c1; // 전방 선언
class c2  // c2의 선언 및 정의
private:
    static c1 member;
    // 클래스 내의 정적 객체는 클래스 외부에서 정의합니다.
    // 때문에 member를 선언하는데 c1의 정의를 알 필요가 없습니다.
};
cs




2. 정의

정의는 식별자와 이름으로부터 코드를 생성하여, 함수가 호출되거나 변수를 사용할 때 생성된 코드를 참조합니다.


또한, 정의는 고유 사양으로 프로그램에는 정의가 하나만 있어야 합니다. 같은 식별자와 이름의 정의가 두개 이상이라면 컴파일 에러가 발생합니다.

반면, 선언만 하고 정의를 하지 않은 경우 링커 단계에서 참조할 코드가 없기 때문에 링커 에러가 발생하는데 예외 사항으로 아래의 경우 정의가 필요없습니다.


1. 함수가 선언만 있고 정의가 없지만 함수를 호출하거나 함수의 주소를 참조하는 일이 없음

2. 정의를 알 필요가 없는 방식으로만 사용됨 (대표적으로 전방 선언..)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int a;            // 변수의 정의1
int b = 10;        // 변수의 정의2
 
int add(int a, int b)
{ // 함수의 정의 (함수 본체가 있습니다.)
    return a+b; 
 
struct C // 구조체의 정의
{
    int a;
    int b;
};
 
class D // 클래스의 정의
{
    int a;
    int b;
};
cs




참고: MSDN(https://msdn.microsoft.com/ko-kr/library/0e5kx78b.aspx)

'C++ > C++ 일반' 카테고리의 다른 글

스택 되감기(Stack Unwinding)  (0) 2018.10.24
인라인(inline) 함수  (0) 2018.10.12
원자성(atomicity)  (0) 2018.10.11
불변속성(invariant)  (0) 2018.10.10
예외 안전성 보장(exception-safety guarantee)  (0) 2018.09.21

+ Recent posts