[C++20 새기능 소개] 모듈 (Modules)

C++20의 새로운 기능들을 소개하는 시리즈의 다섯 번째 글에 오신 것을 환영합니다. 이번 글에서는 코드의 구조와 컴파일 시간을 개선해 줄 모듈(Modules)에 대해 자세히 알아보겠습니다.

모듈(Modules)이란 무엇인가요?

모듈은 C++20에서 도입된 새로운 컴파일 및 코드 조직화 방식으로, 기존의 헤더 파일과 전처리기 매커니즘의 한계를 극복하기 위해 만들어졌습니다. 모듈을 사용하면 컴파일 시간을 단축하고, 코드의 의존성을 명확하게 관리할 수 있습니다.

왜 모듈을 사용해야 할까요?

기존의 헤더 파일 방식은 여러 가지 문제점을 가지고 있습니다:

  • 중복 컴파일: 동일한 헤더 파일이 여러 번 포함되면서 컴파일 시간이 늘어납니다.
  • 전처리기 의존성: 매크로와 같은 전처리기 기능이 복잡성을 증가시킵니다.
  • 의존성 관리의 어려움: 코드의 의존성이 명확하지 않아 유지 보수가 어렵습니다.

모듈을 사용하면 이러한 문제를 해결하고, 더욱 효율적이고 안전한 코드 작성을 도와줍니다.

간단한 예제

기존 헤더 파일 방식

math_functions.h:

// math_functions.h
#pragma once

int add(int a, int b);
int subtract(int a, int b);

 

math_functions.cpp:

// math_functions.cpp
#include "math_functions.h"

int add(int a, int b) {
    return a + b;
}

int subtract(int a, int b) {
    return a - b;
}

 

main.cpp:

// main.cpp
#include <iostream>
#include "math_functions.h"

int main() {
    int result = add(5, 3);
    std::cout << "결과: " << result << std::endl;
    return 0;
}

위 코드에서는 헤더 파일과 소스 파일을 분리하여 함수를 선언하고 정의했습니다.

모듈을 사용한 개선

math_functions.ixx:

// math_functions.ixx
export module math_functions;

export int add(int a, int b);
export int subtract(int a, int b);

 

math_functions.cpp:

// math_functions.cpp
module math_functions;

int add(int a, int b) {
    return a + b;
}

int subtract(int a, int b) {
    return a - b;
}

 

main.cpp:

// main.cpp
import math_functions;
#include <iostream>

int main() {
    int result = add(5, 3);
    std::cout << "결과: " << result << std::endl;
    return 0;
}

 

모듈을 사용하면 export module과 export 키워드를 통해 공개 인터페이스를 정의하고, import를 통해 모듈을 가져올 수 있습니다.

 

모듈의 주요 구성 요소

1. 모듈 선언

모듈 파일은 export module 모듈이름;을 사용하여 선언합니다.

export module my_module;

2. 모듈 구현

모듈 구현부에서는 module 모듈이름;을 사용합니다.

module my_module;

// 구현부 코드

3. 모듈 내보내기

export 키워드를 사용하여 함수, 클래스, 변수 등을 모듈 외부로 공개할 수 있습니다.

export int add(int a, int b);

4. 모듈 가져오기

import 모듈이름;을 사용하여 모듈을 가져옵니다.

import my_module;

자세한 예제: 클래스 모듈화

shapes.ixx:

// shapes.ixx
export module shapes;

export class Circle {
public:
    Circle(double radius);
    double area() const;
private:
    double radius_;
};

 

shapes.cpp:

// shapes.cpp
module shapes;

Circle::Circle(double radius) : radius_(radius) {}

double Circle::area() const {
    return 3.1415 * radius_ * radius_;
}

 

main.cpp:

// main.cpp
import shapes;
#include <iostream>

int main() {
    Circle circle(5.0);
    std::cout << "원의 면적: " << circle.area() << std::endl;
    return 0;
}

모듈의 장점

  • 컴파일 시간 단축: 모듈은 한 번 컴파일된 인터페이스를 재사용하여 컴파일 시간을 줄입니다.
  • 캡슐화 강화: 모듈 내부 구현을 숨기고, 공개 인터페이스만 노출합니다.
  • 전처리기 의존성 감소: 매크로 등의 전처리기 사용을 줄여 코드의 복잡성을 낮춥니다.
  • 의존성 관리 개선: 모듈 간의 의존성을 명확하게 관리할 수 있습니다.

주의 사항

  • 컴파일러 지원: 모듈은 최신 컴파일러와 빌드 시스템의 지원이 필요합니다.
  • 빌드 시스템 설정: 모듈을 사용하려면 빌드 시스템에서 모듈을 인식하고 처리할 수 있어야 합니다.
  • 기존 코드와의 호환성: 기존의 헤더 파일 방식과 혼용할 때 주의가 필요합니다.

결론

C++20의 모듈은 코드의 구조와 컴파일 시간을 혁신적으로 개선하여 개발자들이 더욱 효율적이고 유지 보수하기 쉬운 코드를 작성할 수 있게 해줍니다. 모듈을 활용하여 대규모 프로젝트에서도 의존성을 명확하게 관리해 보세요.

반응형