함수 사용 주의점

  • 매개변수 생성자를 선언하면, 기본 void 생성자는 가려지게 되니 명시적 선언 필요
      class A
      {
          A() = default
          A(int a);
      }

참조로 값 반환 지양하기

  • 참조로 값을 반환하게 되면, c++11의 복사 생략, 이동 시멘틱 도입 이점을 못 봄.
  • 또한, c++17버전 부터 복사 생략은 표준에 의해 강제
  • 값을 반환하는 방식이 컴파일러 최적화가 잘 동작하기에 선호

noexcept

  • 함수가 예외를 던지지 않음을 표현
    void myFunction() noexcept {
      // 이 함수는 예외를 던지지 않습니다.
    }
    struct MyStruct {
      int value;
      // noexcept로 이동 연산자를 정의합니다.
      MyStruct(MyStruct&& other) noexcept : value(other.value) {}
    };

const 메서드

  • 해당 클래스 데이터 멤버를 수정할 수 없게 만들 수 있음
  • get 메서드 구현에 용이
    iinline    int getNumberOfMiles() const
      {
          return m_miles;
      }
  • mutable 멤버 변수는 const 함수 내에서도 값이 변경되어도 컴파일 에러 발생 x

인라인(inline) 함수

  • inline 키워드

    • 초기 의미 : 이 함수를 호출하는 문장을 그냥 이 함수의 내용으로 치환 시켜도 됨.
    • c++17부터 : 여러 정의를 허용 함.
      • 현재 c++은 inline명시 없이도 성능 면에서 유리하다 생각되면 인라인 처리함.
    • 클래스 내부 정의 함수들은 자동 inline
      • 선언만 있을 경우, inline 분류 x <- 클래스 밖 멤버함수 정의를 헤더파일에 안하는 이유.
  • 사용 이유

    • 함수 호출 비용을 줄일 수 있기 때문
    • 헤더파일에 정의해도 문제가 없음
      • 헤더 선언, 소스 정의하면 다른 파일에서 참조 시, 문제 발생
  • 인라인 함수 사용

    • 함수 호출의 오버헤드를 줄이기 위해 컴파일러에게 함수 코드를 호출 대신 함수가 호출된 자리로 직접 삽입하도록 요청하는 함수
    • 작은 함수에서 특히 유용
    • 장점
      • 성능 향상: 함수 호출 오버헤드를 줄일 수 있습니다.
      • 코드 크기 감소: 작은 함수의 경우 인라인으로 처리하면 코드 크기를 줄일 수 있습니다.
      • 캐시 적중률 증가: 인라인 함수가 작은 경우 캐시 적중률이 증가할 수 있습니다.
    • 단점
      • 코드 크기 증가: 인라인 함수가 큰 경우 함수 코드가 여러 번 삽입되어 코드 크기가 증가할 수 있습니다.
      • 디버깅 어려움: 인라인 함수는 코드가 삽입되어 디버깅이 어려울 수 있습니다.
      • 컴파일러가 강제하지 않음: inline 키워드를 사용하더라도 컴파일러가 반드시 인라인으로 처리하지는 않습니다. 최적화에 따라 결정됩니다.
        inline int add(int a, int b) {
        return a + b;
        }

static 멤버 함수

  • 인스턴스의 독립성

    • static멤버 함수는 특정 객체의 인스턴스와 무관하게 호출 가능

      class MyClass {
      public:
        static void staticFunction() {
            // 클래스 레벨에서 호출 가능
        }
      };
      
      MyClass::staticFunction(); // 객체 생성 없이 호출 가능
  • 일반적으로 static 멤버 변수의 값 조정하는 것은 static 멤버 함수 사용을 권장(가독성을 위해)

멤버 함수 내부 static 변수

  • 해당 멤버 함수가 호출이 끝나도 값을 계속 유지
  • 정적 로컬 변수 라고 함
      void staticFunction() {
          static int count = 0;
          count++;
          std::cout << "Count: " << count << std::endl;
      }
  • 함수 호출 간에만 값을 유지하고 싶을 떄 좋음

메소드와 함수의 차이

  • 함수
    • 독립적으로 존재
    • 직접 호출 가능
  • 메소드
    • 객체의 기능을 구현하기 위한 클래스 내부에 존재
    • 객체(클래스)를 통해 호출
  • 클래스 메소드
    • 클래스에 속한 메소드
    • 클래스를 통해 접근
  • 인스턴스 메소드
    • 클래스의 객체에 속한 메소드
    • 객체를 통해 접근
  • 정적 메소드
    • 함수와 비슷한 역할을 하지만, 클래스에 속하는 메소드
  • 동적 메소드
    • 동적으로 생성되거나 런타임에 바인딩되는 메소드
    • 리플렉션(JAVA), 델리게이트(C#), Python, JS

함수명 구하기(__func__)

  • 모든 함수는 내부적으로 __func__ 라는 로컬 변수 정의
  • 현재 함수의 이름을 담음
      int addNum()
      {
          cout << "E function " << __func__ << endl;
      }

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

튜플(Tuple)  (0) 2025.03.05
클래스  (0) 2025.03.03
enum_class  (0) 2025.03.03
C++ 변수  (0) 2025.03.03
C++ 여러가지 기본  (0) 2025.03.02

아래 차이점은 현재는 거의 적용되지 않습니다

enum vs enum_class

  • enum (C 스타일 열거형):

    • 기본적으로 정수형 값을 가집니다.
    • 이름 충돌이 발생할 수 있습니다. 같은 이름의 변수orenum 값 이름이면, 다른 enum 값 이름 에서 충돌이 발생할 수 있습니다.
    • enum 값이 암시적으로 정수형으로 변환될 수 있습니다.
      • 최신 컴파일러에서는 사전에 대부분 방지 되기에, enum class와 별 차이 없는 경우가 많음. (그래도 가급적 enum class 사용 권장)
  • enum class (C++11 스타일 열거형):

    • 강력한 형식 체계를 제공합니다.
    • 이름 충돌이 발생하지 않습니다. 같은 이름의 열거형 값을 다른 enum class에서 사용할 수 있습니다.
    • enum class 값은 명시적으로 변환하지 않는 한 다른 형식으로 변환되지 않습니다.

using enum

  • c++20 부터 지원
  • using namespace 처럼 열거값을 짧게 쓰도록 지원
    • 사용 시, 스코프 최소화 권장 <- 개인적으로 너무 긴 거 아니면 안 쓰는게 좋을 듯 함.
      enum class Color {
        Red,
        Green,
        Blue
      };
      void printColor(Color color) {
        using enum Color;  // Color 열거형 값을 현재 스코프에서 사용할 수 있도록 함
        switch (color) {
            case Red:
                std::cout << "The color is red" << std::endl;
                break;
            case Green:
                std::cout << "The color is green" << std::endl;
                break;
            case Blue:
                std::cout << "The color is blue" << std::endl;
                break;
        }
      }

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

클래스  (0) 2025.03.03
함수  (1) 2025.03.03
C++ 변수  (0) 2025.03.03
C++ 여러가지 기본  (0) 2025.03.02
C++20: 모듈 선언  (0) 2025.03.02

C++ 변수

  • C++ 변수 선언
    1) 키워드 이름으로 사용 불가
    2) 숫자로 시작 불가
    3) 특수문자는 _와 $만 사용 가능
    4) 공백 포함 불가
    5) 대소문자 구분
  • 변수 : 4가지 속성
    • 이름 : x
    • 값 : 40
    • 데이터타입(메모리크기) : 정수
    • 메모리 주소

균일 초기화(uniform initialization)

  • c++11 이후 부터, 대입 문법 대신 균일 초기화 사용을 권장
    • int a = 7 -> int a {7}

byte 사용 시, 주의점

  • C++17 이전
    • char or unsigned char 을 통해 표현
        char a = 0123 // 8진수
        char b = 0b111011 // 2진수
  • c++17 이후 std::byte - cppreference.com
    • std::byte 를 통해 표현 (고정 1byte) <- <cstddef> 헤더
    • 산술 연산자 사용 불가
    • 정수 타입이 아니기에 직접 대입 할당 및 비교 불가
      // std::byte y = 1; // Error: cannot convert int to byte.
      std::byte y{1}; // OK
      // if (y == 13) {} // Error: cannot be compared.
      if (y == std::byte{13}) {} // OK, bytes are comparable
      // b *= 2; // Error: b is not of arithmetic type

숫자 경곗값

  • <limits>std::numeric_limits<type> 을 통해 해당 타입 경계값 파악 가능

캐스트

  • 변수의 타입을 실행 중에 바꾸는 것

      float myF {3.14f};
      int i1 { (int)myF };  // c 방식 명시변환
      int i2 { static_cast<int>(myF) } // c++ 권장 방식
  • 업캐스팅

    • 자식 클래스 객체를 부모 클래스 타입으로 변환하는 것

    • 암시적 변환 처리 가능

    • 다형성(polymorphism) 구현에 사용

      class Animal {
      public:
        void speak() { std::cout << "Animal speaks" << std::endl; }
      };
      
      class Dog : public Animal {
      public:
        void speak() { std::cout << "Dog barks" << std::endl; }
      };
      
      Dog dog;
      Animal* animal = &dog;  // 업캐스팅
      animal->speak();  // Animal speaks
  • 다운캐스팅

    • 부모 클래스 객체를 자식 클래스 타입으로 변환하는 것
    • 명시적으로 수행되어야 함
    • 잘못된 다운캐스팅은 런타임 오류
      • RTTI(Runtime Type Information) 사용
        Animal* animal = new Dog();
        Dog* dog = dynamic_cast<Dog*>(animal);
        if (dog) {
        dog->speak();  // Dog barks
        } else {
        std::cout << "다운캐스팅 실패" << std::endl;
        }

부동소수점

  • NaN 검증 : std::isnan() <- <cmath>
  • Infinity 검증 : std::isinf() <- <cmath>

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

함수  (1) 2025.03.03
enum_class  (0) 2025.03.03
C++ 여러가지 기본  (0) 2025.03.02
C++20: 모듈 선언  (0) 2025.03.02
C++ 빌드 과정  (0) 2025.03.02

목차

  • class Parameter
  • C++ 복사
  • C++ 객체배열 주의점
  • cin 버퍼 비우기
  • std io에서 bool값 true,false 로 출력
  • rand 함수
  • struct Parameter
  • c 표준라이브러리 c++ 표기
  • 자릿수 구분자 (숫자 자릿수 가독성용)
  • switch 폴스루(fallthrough)
  • 함수명 구하기(__func__)

class Parameter

C++ 복사

  • int, char 배열은 기본적으로 DeepCopy를 지원.
  • 객체의 경우, 기본적으로 ShallowCopy를 지원.

C++ 객체배열 주의점

  • 객체 배열을 생성 시, 해당 객체들의 기본 생성자가 호출됨.

cin 버퍼 비우기

  • cin 과 string::getline()을 혼용해서 사용하다 보면 cin의 버퍼를 비워야 할 때가 있음.
  • 방법 1. cin.ignore()
    • cin.ignore(numeric_limits<streamsize>::max(), '\n');
  • 방법 2. cin.readsome()
    • cin.readsome(nullptr, cin.rdbuf()->in_avail))
  • 방법 3. cin.get()
    • while(cin.get('\n'))

std io에서 bool값 true,false 로 출력

  • bool값을 0은 false, 1은 true 로 출력할 수 있게 해준다.
  • iomanip <- 헤더 파일 필요
    #include <iostream>;
    #include <iomanip>
    std::cout << std::boolalpha;

rand 함수

  • c++도 기본 설정으로 시드 고정이기에 시드값을 가변해 줘야한다.

    struct Parameter

  • struct 키워드를 포함하여 구조체를 매개변수로 사용할 수 있습니다.

c 표준라이브러리 c++ 표기

  • 앞에 c 를 붙이고 .h를 뺀다.
    • <stdio.h> -> <cstdio>, <math.h> -> <cmath>

자릿수 구분자

  • 23'456'789 , 0.123'456f 방식으로 ' 를 사용해서 구분 가능
    • C#, Java에서는 _를 사용.

함수명 구하기(__func__)

  • 모든 함수는 내부적으로 __func__ 라는 로컬 변수 정의
  • 현재 함수의 이름을 담음
      int addNum()
      {
          cout << "E function " << __func__ << endl;
      }

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

enum_class  (0) 2025.03.03
C++ 변수  (0) 2025.03.03
C++20: 모듈 선언  (0) 2025.03.02
C++ 빌드 과정  (0) 2025.03.02
디버그 출력  (0) 2025.03.02

기존 빌드

  • c++빌드 과정
  • 헤더 파일의 내용이 복사되어 파일에 들어감 <- "Transition Unit" 방식

모듈 빌드(import)

참고 : devshovelinglife_모듈

  • 한번 도입되며 비용이 거의 없음
    • 재사용 가능하기에 컴파일 시간 단축
    • 여러 소스 파일에서 재사용 가능하기에 코드 중복 감소
  • 모듈 인터페이스와 구현 파일이 분리되어 빌드 의존성 관리 용이
    • 모듈 인터페이스를 통해 외부 노출 부분과 내부 숨김 부분이 나누어져 캡슐화 강화
  • 모듈 간의 의존성을 명확하게 정의 가능하여, 헤더 파일방식 보다 효율적

모듈 선언

참고 : kukuta_모듈

  • vs 기준 확장자가 .ixx인 파일 <- 모듈 인터페이스 단위
      // ModuleA.ixx 모듈 인터페이스 파일
      export module ModuleA;      // 내보낼 모듈의 이름 지정
      namespace Foo
      {
          ​​​​export int MyIntFunc()  // 모듈에서 내보낼 기능(함수)의 인터페이스를 지정
          ​​​​{
              ​​​​​​​​return 0;
          ​​​​}
          ​​​​void InternalMyFunc()   // 모듈 내부에서만 사용하는 전역 함수
          ​​​​{
          ​​​​}
          export int gobalInt;   // 모듈에서 내보내는 전역 변수
          export class moduleClass{};  // 모듈에서 내보내는 클래스
      }

하위 모듈

  • 모듈의 크기가 커지면, 하위 모듈로 분할하는 것을 권장

  • 하위 모듈은 개별 파일로 구성

      // mainmodule.ixx
      export module mainmodule;
    
      export import :submodule1;
      export import :submodule2;
    
      export namespace mainnamespace {
          void mainFunction() {
              // 상위 모듈의 함수 구현
          }
      }
      //==================
      // submodule1.ixx
      module mainmodule:submodule1;
      export namespace mainnamespace::subnamespace1 {
          void subFunction1() {
              // 하위 모듈 1의 함수 구현
          }
      }
      //===================
      // submodule2.ixx
      module mainmodule:submodule2;
    
      export namespace mainnamespace::subnamespace2 {
          void subFunction2() {
              // 하위 모듈 2의 함수 구현
          }
      }
      //===================
      import mainmodule;
      int main() {
          mainnamespace::mainFunction();
          mainnamespace::subnamespace1::subFunction1();
          mainnamespace::subnamespace2::subFunction2();
          return 0;
      }

번외

  • gcc의 경우는, msvc와 확장자명, 전처리문의 위치 문제 등이 있을 수 있음.

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

C++ 변수  (0) 2025.03.03
C++ 여러가지 기본  (0) 2025.03.02
C++ 빌드 과정  (0) 2025.03.02
디버그 출력  (0) 2025.03.02
C++ 저장&링킹  (1) 2025.03.01

요약

컴파일러 내부 단계

  • Phase1. : < 여기부터 전처리 단계 >

    • 소스 파일 문자 해석 (기본 Basic source character set(공백, 영문자, 특수문자{총 96}) 및 다른 모든 문자 \u(유니코드) 치환
  • Phase2. :

    • \ 문자 해석
  • Phase3. :

    • 주석, 공백 문자, 전처리 토큰(Preprocessing token)(define, include 등 컴파일 전에 처리되는 것)들로 분리
    • 특이사항
      • 주석은 공백 문자 하나로 변경
      • maximal munch 규칙 : 가장 긴 전처리 토큰을 구성하려고 함
        • int a = bar+++++baz -> bar++, ++ + baz
        • int b = 0xE+foo -> 0xe+,foo
  • Phase4.

    • 전처리기 실행 단계 (Phase2)에서 분리한 전처리 토큰 적용.
      • #include : 지정 파일 내용 복사
      • #define : 정의된 매크로 사용해서 코드 치환
      • #if, #ifndef : 구문 실행해서 코드 치환
        • 헤더 가드에서 중복 내용 개행문자처리
      • #pragma : 명령문 해석
    • 컴파일 할 떄, -E 옵션으로 컴파일 시, 전처리 끝난 후의 파일 확인 가능

    • @명심 : #include로 복사된 헤더 파일은 1~4 단계를 다시 거침 (전처리문 더 이상 없을 떄까지 반복)
    • TMI :
      • C++ 20 에서는 모듈(module) 이라는 개념을 도입해서 이와 같은 문제를 해결할 수 있습니다. 모듈은 다른 파일의 클래스의 함수들을 참조할 수 있지만 #include 를 할 때 처럼 해당 파일의 모든 내용을 불러오지는 않습니다. 물론 아직 (2020년 10월 현재) 모듈이 정식으로 컴파일러에서 구현된 것은 아니라서 이를 사용하려면 조금 시간이 걸릴 것으로 보입니다.
  • Phase5.

    • 소스 코드 문자 셋(UTF-8 등)에서 실행 문자 셋(OS 문자{ANSI 코드 페이지 등})으로 변경
  • Phase6.

    • 인접한 문자열 합치기

      std::cout << "abc"
         "def";
      
      {합치기}  
      std::cout << "abcdef";  
  • Phase7. : < 여기부터 컴파일 단계 >

    • 해석 유닛 생성 (TU)
      • 소프 코드 컴파일, 인터프리팅 할 떄 사용되는 단위
      • 특정 파일과 해당 파일에 포함된 모든 헤더 파일 집합
      • TU에 존재하는 모든 변수, 함수, 클래스, 템플릿 등등의 정의는 유일, inline이 아닌 모든 함수 변수 정의는 전체 프로그램에서 유일 (One Definition Rule; ORD)
        • 선언은 여러개 있어도 되지만, 정의는 유일.
        • int f(); <- 선언이라 여러개 가능
        • int f(() {return0;} <- 정의라 유일
        • 헤더파일에 정의 시, 다른 소스파일이 #include할 떄, 2 개의 서로다른 TU에 같은 정의가 들어가게 되서 ORD 규칙 가능
    • 흔히 알려진 컴파일 이루어지는 곳
    • 전처리기 토큰 -> 컴파일 토큰 변환
    • 컴파일 토큰 -> (해석) -> 해석 유닛(Translation Unity; TU)
    • 해석 유닛은 소스 파일 별 1개 씩 존재
      • 서로 독립적으로 컴파일 됨
  • Phase8.

    • 인스턴스 유닛 생성
    • 탬플릿 정의 위치 확인 -> 인스턴스화
    • 목적 코드 생성 ( .obj 같은 목적 파일 생성)

링킹 단계

  • 목적 파일 및 외부 라이브러리 파일을 모아서 실행 파일 생성
  • 결과물이 각기 다른 파일 형태
    • 다른 실행 파일 (Portable Executable;PE <- exe 파일, Executable and Linkable Format;ELF 등)

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

C++ 여러가지 기본  (0) 2025.03.02
C++20: 모듈 선언  (0) 2025.03.02
디버그 출력  (0) 2025.03.02
C++ 저장&링킹  (1) 2025.03.01
C++ 컨테이너 클래스  (0) 2025.03.01

OutputDebugString

  • Windows 환경에서 제공되는 디버그 출력 함수

  • <Windows.h> 헤더에 포함

  • 출력 창의 디버그창에만 표시됨에 유의

    #include <windows.h>
    
    int main() {  
    OutputDebugString(TEXT("Hello, Debug World!"));  
    return 0;  
    }
  • print처럼 포맷 적용하는 법 : https://blog.codingcat.kr/76

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

C++20: 모듈 선언  (0) 2025.03.02
C++ 빌드 과정  (0) 2025.03.02
C++ 저장&링킹  (1) 2025.03.01
C++ 컨테이너 클래스  (0) 2025.03.01
new&delete  (0) 2025.03.01

참고 문헌 : 씹어먹는 C++ - <20 - 3. 코드 부터 실행 파일 까지 - 링킹 (Linking)>

저장 방식 지정자 (Storage class specifier)

  • static
  • thread_local
  • extern
  • mutable <- 저장 기간과 링크 방식에 영향x
  • auto <- c++11 부터 제거됨 (auto 키워드로 대체)
  • register <- c++17 부터 제거됨

저장 기간 (Storage duration)

  • ___ 객체들에게만 해당
  • 자동 저장 기간
    • scope{} 안에 정의 된 녀석들
      • static, extern, thread_local 키워드 지정 제외
    • 지역 변수
  • static 저장 기간
    • 프로그램 시작할 떄 할당, 끝날 때 소멸
    • 함수 밖에 정의된 것들 (전역변수,namespace 단위)
    • static or extern 정의 객체
  • 쓰레드 저장 기간
    • 쓰레드 시작할 떄 할당, 종료될 떄 소멸
    • 각 쓰레드들이 해당 객체 복사본 가짐
    • thread_local 선언 객체
  • 동적 저장 기간
    • 동적 할당 함수를 통해 할당, 해제되는 객체 (new, delete)
    • 링커에서 어디에 배치 할 지 중요 정보로 사용됨

링크 방식(lINKAGE)

  • 링크 방식 없음 (No linkage)
    • 지역 함수들은 {}안에 링크 방식이 없는 상태로 정의되어 있음
  • 내부 링크 방식 (Internal Linkage)
    • static으로 정의된 함수, 변수, 템플릿 함수, 템플릿 변수 등.
    • 같은 TU 안에서만 참조
      • C#의 static이 다른 파일에서 사용가능한 것과 달리, Cpp에서는 사용 불가.
  • 외부 링크 방식 (External Linkage)
    • 외부 링크 방식으로 정의된 개체는 다른 TU에서도 참조 가능
    • 언어 링크 방식 정의가 가능해, 다른 언어 사이에서 함수 공유 가능
    • 전역 변수&함수, extern 방식,
  • 이름 맹글링 (Name Mangling)
    • 목적 코드 생성 시에 함수 이름이 바뀜. (c의 경우, 그대로)
    • 같은 이름의 함수 정의 가능 <- 맹글링하는 이유
      • 함수 이름 자체만으로 어떤 함수 호출할 지, 구분 불가
      • C# & Java에서 리플렉션이 가능한 이유 : 맹글링을 하지 않음.
    • extern : 이름 맹글링을 하지 말라고 컴파일러에 전달

링킹

  • 각각의 TU들에서 생성된 목적 코드들을 한데 모아서 하나의 실행 파일을 만듦
  • nm 프로그램을 사용하여, 목적 코드 확인가능
    • 대문자 알파벳 심볼 : 외부 링크 방식
    • 소문자 알파벳 심볼 : 내부 링크 방식
    • b, b : 초기화 되지 않은 데이터 섹션 (BSS 섹션)
    • D, d : 초기화 된 데이터 섹션
    • T, t : 텍스트 (코드) 섹션
    • R, r : 읽기 전용 (read only) 섹션
  • 목적 코드들은 링킹 전 까지 심볼 위치 확정 x
  • 재배치 (Reloaction)
    • 재배치 테이블(Relocation Table)
      • 심볼 위치 확정이 되면 값을 바꿔야 할 부분을 적어놓은 테이블
      • R_X86_64_PC32
        • 상대 오프셋 재배치 유형
        • 정적,동적 링크 모두에서 사용 (특정 상황에서 동적 링크는 안될 수 있음)
        • 4바이트 영역을 S + A - P 를 계산한 값을 치환하라
          • S : 재배치 후에 해당 심볼 실제 위치
          • P : 재배치 해야하는 부분 위치
          • A : 더해지는 값, 재배치 테이블에서 확인
          • -> 공유(동적)라이브러리는 섹션의 위치를 특정할 수 없어 사용 불가
      • R_X86_64_PLT32
        • 프로시저 링크 테이블(PLT)를 사용하는 동적 링크
        • 함수 호출 시 런타임에 해당 함수의 실제 주소를 해결하기 위해 사용
        • 동적 라이브러리에서 많이 사용

정적 링킹

  • 정적 라이브러리에 사용
    • 프로그램에 필요한 모든 코드가 들어 있음.
      • 환경에 크게 관계 없이 실행 가능
      • 파일 크기가 매우 큼 ( 용량 낭비 )
    • 미리 컴파일된 라이브러리, 재컴파일 필요 X
      • 새 버전을 추가하면, 링킹하고 있는 프로그램 다시 컴파일 필요
    • 사용하지 않는 함수까지 전부다 포함됨 ( 용량 낭비 )
  • 링크 타임에 바인딩
  • 모든 프로그램이 같은 라이브러리 사용하여도, 각각 동일하게 라이브러리 코드 포함 해야 함
  • 외부 링크 방식 심볼 호출 부분은 해당 심볼의 실제 주소 값으로 대체(고정 값)
    • 메모리 임의 지점에 불러오면 찾을 수 없음

동적 링킹

  • 동적 라이브러리(공유 라이브러리)에 사용
    • 실제 물리 메모리에 라이브러리 위치, 가상 테이블로 참조
      • 각각의 프로세스에는 고유의 페이지 테이블
      • 코드의 크기가 달라, 가상메모리에 위치한 주소가 각자 다름
      • -> 가상 메모리물리 메모리 변환하는 페이지 테이블이 해결
    • 컴파일러를 통해 제작
      • 위치와 무관한 코드 (Position Independent Code - PIC) 를 만들라는 의미의 -fpic 인자를 전달해줘야 함.
        $ g++ -c -fpic foo.cc
        $ g++ -c -fpic bar.cc
        $ g++ -shared foo.o bar.o -o libfoobar.so

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

C++ 빌드 과정  (0) 2025.03.02
디버그 출력  (0) 2025.03.02
C++ 컨테이너 클래스  (0) 2025.03.01
new&delete  (0) 2025.03.01
포인터  (0) 2025.02.22

+ Recent posts

let textNodes = document.querySelectorAll("div.tt_article_useless_p_margin.contents_style > *:not(figure):not(pre)"); textNodes.forEach(function(a) { a.innerHTML = a.innerHTML.replace(/`(.*?)`/g, '$1'); });