ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • C++ 템플릿 클래스는 언제 생성될까?
    Programming Language/C++ 2016. 12. 10. 15:58

    신입으로 취업 전, soen.kr 이라는 웹사이트에서 C++ 을 공부했었는데 그 사이트에는 이렇게 설명되어 있다.

     

    컴파일러에 의해 구체화된 함수는 실행 파일에 실제로 존재하며 컴파일 단계에서 미리 만들어지므로 실행시의 부담은 전혀 없다. 함수가 호출될 때 만들어지는 것이 아니다. 대신 매 타입마다 함수들이 새로 만들어지므로 구체화되는 수만큼 실행 파일의 용량이 늘어난다. 템플릿은 크기를 포기하는 대신 속도를 얻는 방식인데 크기와 속도는 항상 반비례 관계에 있다.

     

    (원문 : http://soen.kr/lecture/ccpp/cpp3/31-1-2.htm)

     

     

    함수에 대한 설명이긴 하지만 클래스와 다를 게 없을 거라고 생각했다.

     

    그런데 회사에서 어떤 분께 템플릿/제네릭 클래스는 객체를 생성할 때 클래스가 만들어진다라는 식으로 설명을 들었다.

     

    뭔가 이상한 점을 느껴서 C++의 템플릿 클래스가 어느 시점에 생성되는지 직접 확인해 보려고 한다.

    C++의 템플릿 클래스와 자바의 제네릭 클래스는 차이점이 있기는 하지만 사용 목적은 같고 생성 시점도 같을 것으로 추측되므로 자바의 제네릭 클래스 생성 시점 확인은 생략한다.

     

     

    먼저 아래와 같은 프로그램을 컴파일 했다.

    T형 a, b 변수를 가지는 템플릿 클래스이다.

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #include <stdio.h>
     
    template <typename T>
    class Template
    {
    public:
        T a, b;
        Template()
        {
            printf("constructor\n");
        }
    };
     
     
    void main()
    {
        Template<int> test1;
    }

     

     

     

     

     

     

    31232바이트 크기로 컴파일이 되었다.

    컴파일 시점에 소스코드를 읽어서 클래스를 추가적으로 생성한다고 했으니 다른 타입도 여러 가지 만들어서 용량이 커지는지 확인해 보았다.

    아래 코드는 32256 크기로 컴파일이 되었다.

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    #include <stdio.h>
     
    template <typename T>
    class Template
    {
    public:
        T a, b;
        Template()
        {
            printf("constructor\n");
        }
    };
     
     
    void main()
    {
        Template<int> test1;
        Template<float> test2;
        Template<char> test3;
        Template<double> test4;
        Template<short> test5;
        Template<long> test6;
    }

     

     

     

     

     

    각각 31232, 32256 크기로, 다른 자료형으로 템플릿 클래스를 사용할 때마다 용량이 늘어나는 것을 확인할 수 있었다.

     

     

     

    이번에는 단순히 용량이 아니라 실제 프로그램이 실행되었을 때 어떤 클래스가 생성되어 있는지 확인해 보았다.

    일단 코드를 조금 수정했다. (getchar()은 프로그램이 종료되는걸 막는 용도이다.)

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    #include <stdio.h>
     
    template <typename T>
    class Template
    {
    public:
        T a, b;
        Template()
        {
            printf("constructor\n");
        }
    };
     
     
    void main()
    {
        if(1 == 2)
        {
            Template<int> test1;
            Template<float> test2;
            Template<char> test3;
        }
        
        getchar();
    }

     

     

     

     

     

    1은 2와 같지 않아서 조건식 내부 코드에 들어가지 않을 것이다.

    따라서 test1, test2, test3 변수는 생성되지 않을 것이고, Template<int>, Template<float>, Template<char>은 소스코드 상에서만 존재하며 실제로 사용되지는 않는다.

     

    소스코드에 작성해 둔 Template<int>, Template<float>, Template<char> 클래스가 구현되어 있고, 작성하지 않은 Template<double> 따위의 클래스가 구현되어 있지 않다면 컴파일 시점에 클래스를 구현한다는게 증명이 되는 셈이다.

     

    직접 리버스 엔지니어링을 해서 확인을 해보았다.

    아래 사진처럼 int와 char, float 로 구현된 클래스는 찾을 수 있었다.

     

    (char)

     

     

     

     

    (int)

     

     

     

     

     

     

    하지만 소스코드에 없는 double, short, long 등의 자료형으로 구현된 클래스는 존재하지 않았다.

    따라서 템플릿 클래스는 컴파일 시점에 코드를 읽어서 사용할 템플릿을 미리 빌드한다는 것을 알 수 있었다.

    역시 무작정 듣는 이야기를 믿기 보다는 직접 눈으로 보고 확인하는 것이 정확한 것 같다.

Designed by Tistory.