C++/Syntax 2021. 3. 10. 21:07

extern

  • 함수의 경우 기본적으로 extern이 생략되어 있는 것이다.

  • 변수의 경우 가져다 쓰는 파일에서 forward declaration 할 때 앞에 extern을 붙여주어야 한다.

    • 이를 통해 External Linkage 속성을 가진다.

    main.cpp

    #include <iostream>
    
    extern int a;  // OK
    int a;         // Linking Error
    
    int main()
    {
      using namespace std;
    
      cout << a << endl;
    }

    variable.cpp

    extern int a = 100;  // OK
    int a = 100;         // OK

메모리 절약 팁 (extern)

  • 헤더 파일의 namespace에서 const 키워드로 상수를 만들면 파일마다 메모리를 따로 사용하여 낭비하는 꼴이 된다.(아래 예제 참고)

  • 원인

    • #include 는 파일의 내용을 그대로 갖다붙인다.

    • namespace 안에 존재하기는 하지만 각각의 파일에서 전역 변수로 작동한다.

    • const 키워드는 기본적으로 Internal Linkage 속성이다.

    • 따라서 같은 전역변수 이름을 쓰더라도 const 덕분에 충돌이 일어나지 않는다.

    • 결국 다른 주소 공간에 있는 데이터를 불러오는 것과 같다.

    main.cpp

    #include <iostream>
    #include "MyConstants.h"
    
    void test();
    
    int main()
    {
      using namespace std;
    
      cout << Constants::pi << ' ' << &Constants::pi << endl;
      test();
    }

    MyConstants.h

    #pragma once
    
    namespace Constants
    {
      const double pi(3.141592);
      const double gravity(9.8);
    }

    test.cpp

    #include <iostream>
    #include "MyConstants.h"
    
    void test()
    {
      using namespace std;
    
      cout << Constants::pi << ' ' << &Constants::pi << endl;
    }
  • 이를 방지하기 위해서는 별도의 MyConstants.cpp 파일을 생성한 후, extern 키워드로 내보내야 한다.

    • 위의 코드를 아래와 같이 변경하면 같은 메모리 공간에 접근하는 것을 알 수 있다.

    main.cpp

    #include <iostream>
    #include "MyConstants.h"
    
    void test();
    
    int main()
    {
      using namespace std;
    
      cout << Constants::pi << ' ' << &Constants::pi << endl;
      test();
    }

    MyConstants.h

    #pragma once
    
    namespace Constants
    {
      extern const double pi;
      extern const double gravity;
    }

    MyConstants.cpp

    namespace Constants
    {
      extern const double pi(3.141592);
      extern const double gravity(9.8);
    }

    test.cpp

    #include <iostream>
    #include "MyConstants.h"
    
    void test()
    {
      using namespace std;
    
      cout << Constants::pi << ' ' << &Constants::pi << endl;
    }

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

C++ 자료형 추론 (auto, decltype)  (0) 2021.03.10
C++ using  (0) 2021.03.10
C++ 범위 지정 연산자 (Scope Resolution Operator)  (0) 2021.03.10
C++ 비트 연산자 (Bitwise Operator)  (0) 2021.03.10
C++ 쉼표 연산자 (Comma Operator)  (0) 2021.03.10