Skip to main content

Rust는 C++을 대체할 수 있을까?

About 2 minRustC++Article(s)blogyozm.wishket.comrustrscppc++c-plus-plus

Rust는 C++을 대체할 수 있을까? 관련

Rust > Article(s)

Article(s)
C++ > Article(s)

Article(s)

Rust는 C++을 대체할 수 있을까? (1) | 요즘IT
Rust. 최근 Reddit이나 HackerNews를 보면 아주 빈번하게 접할 수 있는 프로그래밍 언어입니다. 이 언어는 시스템 프로그래밍 언어로, 특히 C와 C++의 단점을 보완하고자 하는 목적에서 탄생했습니다. 더 나은 안정성과 성능, 특히 병렬 처리의 안전성을 핵심 목표로 개발되었죠. 따라서 C++을 대체할 수 있는 언어로 유명한데요. C++의 오랜 사용자 입장에서 Rust가 과연 어떤 메커니즘으로 이를 대체하고자 하는지 알아두면 좋은 시점이라고 생각했습니다. 과연 Rust는 어떤 특징이 있길래, 이렇게 인기를 얻고 있는 걸까요?

Rust. 최근 레딧(Reddit)이나 해커뉴스(HackerNews)를 보면 아주 빈번하게 접할 수 있는 프로그래밍 언어입니다.

이 언어는 C++을 대체할 수 있는 언어로 유명한데요. C++의 오랜 사용자 입장에서 Rust가 과연 어떤 메커니즘으로 C++을 대체하고자 하는지 알아두면 좋은 시점이라고 생각했습니다.

과연 Rust는 어떤 특징이 있길래, 이렇게 인기를 얻고 있는 걸까요?


Rust! 어떤 언어인지 아시나요?

Rust는 누가 만들었을까?

Rust는 지난 2010년, 모질라 재단의 후원으로 개발된 프로그래밍 언어입니다. 모질라 재단은 파이어폭스와 썬더버드 같은 유명한 오픈 소스 프로젝트로 잘 알려져 있습니다. 초기 개발자는 그레이던 호어(Graydon Hoare)로 모질라에서 근무하며 Rust의 기본 아이디어를 구상하고 구현하기 시작했다고 합니다. 호어의 개인 프로젝트였던 Rust는 곧 모질라 재단의 공식적인 지원을 받게 되었고, 2020년 Rust 재단이 설립되며 언어 개발과 생태계가 더욱 활발해졌습니다.

이러한 Rust는 시스템 프로그래밍 언어로, 특히 C와 C++의 단점을 보완하고자 하는 목적에서 탄생했습니다. 더 나은 안정성과 성능, 특히 병렬 처리의 안전성을 핵심 목표로 개발되었죠.

Rust의 5가지 특징을 알아봅시다

Rust의 주요 특징은 이렇습니다.

  • 높은 메모리 안전성: 컴파일 시점에서 메모리 접근 오류를 방지함으로써 런타임에 발생할 수 있는 여러 오류를 사전에 차단합니다.
  • 뛰어난 성능: C, C++과 유사한 수준의 고성능을 제공합니다.
  • 병렬 처리의 안전성: 데이터 경합을 방지하고 안전한 병렬 처리를 지원합니다.
  • 고유 소유권 시스템: 고유한 소유권 시스템인 ‘빌림 검사기(Borrow Checker)’ 도입으로 메모리 관리의 효율성을 극대화합니다.
  • 풍부한 타입 시스템과 패턴 매칭: 다양한 타입 시스템과 패턴 매칭을 적용해 코드의 안전성과 가독성을 높이는 데 기여합니다.

어째서 실리콘 밸리에선 이렇게 핫할까요?

Rust는 실리콘 밸리의 주요 기업들로부터 관심을 받고 있습니다. 나사, 마이크로소프트, 리눅스 커뮤니티, 안드로이드 프로젝트 등 여러 곳에서 개발 언어로 Rust를 선택하고 있죠. 특히 새로 도입할 기술을 결정하는 관점이 아닌 기존 C++ 코드를 재작성 하는 선택지로 많이 쓰이고 있습니다. (참고 글open in new window)

여러 가지 Rust의 특징 중에서도 아래 특징이 큰 영향을 주었을 겁니다.

  • 안정성: 메모리 안전성과 병렬 처리 안전성을 보장하여 소프트웨어의 안정성을 높일 수 있습니다.
  • 성능: 시스템 프로그래밍 언어로서 C++와 동등한 성능을 제공하면서도, 더 나은 메모리 관리 기능을 갖추고 있습니다.
  • 생산성: Rust의 강제된 메모리 관리 규칙과 문법, 또한 실수의 여지를 줄이는 규칙은 초기 학습 비용이 크지만, 이에 적응한 개발자들의 생산성과 안정성을 올려줍니다.

C++ vs. Rust. 그래서 무엇이 다른가요?

하나하나 짚어보며 차이점을 알아볼까요?

1. 메모리 안전성
  • .C와 C++: C와 C++은 수동 메모리 관리를 요구합니다. 따라서 개발자가 직접 메모리를 할당하고 해제해야 하는데요. 그 때문에 메모리 누수, 잘못된 메모리 접근(예: 댕글링 포인터, 버퍼 오버플로우) 같은 문제가 발생하기 쉽습니다.
  • .Rust: Rust는 고유한 소유권 시스템 ‘빌림 검사기(Borrow Checker)’를 적용해 메모리를 자동으로 관리합니다. 이 시스템은 컴파일 타임에 메모리 안전성을 보장하고, 댕글링 포인터나 버퍼 오버플로우 같은 메모리 접근 관련 문제를 방지합니다. 또한 생명주기(Lifetime) 시스템에서 참조가 유효한 기간을 명시적으로 관리하며 메모리 안전성을 강화합니다.

예시 코드로 Rust의 특징을 자세히 알아봅시다

1. 동적 메모리 관리

메모리를 동적으로 관리하는 것은 현대 언어에서는 소수 언어만 가진 특징입니다. 메모리를 잘 관리하면 고성능 애플리케이션을 만들 수 있습니다. 대신 실수의 여지가 있죠.

수동으로 메모리 할당 해제를 해야 하는 것은 C++ 문법의 단점입니다. 물론 C++의 경우에도 스마트 포인터를 쓰면 보강되긴 하지만, 강제된 규칙은 아닙니다. 따라서 C++의 표준적인 메모리 관리 규칙에서는 엄연한 단점이라고 볼 수 있습니다.

C++ 코드
C++ 코드

여기서 delete 키워드를 활용한 메모리 해제 부분을 누락한다면, 메모리 누수가 발생하게 됩니다.

Rust 코드
Rust 코드

예시 코드에서 my_objectuse_my_class 함수 끝에서 자동으로 소멸하며 메모리가 해제됩니다. 이처럼 Rust의 소유권 시스템은 자동으로 메모리를 관리합니다. 사실 이러한 규칙은 C++의 스마트 포인터, 그리고 자바 등 레퍼런스 카운팅 기반의 Garbage Collection으로 잘 구현되어 있습니다. 색다를 것 없다고 느낄 수도 있겠죠.

그러나 차이가 없다면, Rust가 지금보다 주목을 덜 받았을 겁니다. Rust의 소유권 시스템에 대해 더 자세히 알아봅시다.

2. 생명 주기와 소유권 시스템

C++에서는 개발자가 직접 메모리를 관리해야 합니다. 따라서 메모리 해제를 잊어버리는 경우, 메모리 누수가 발생할 수 있습니다. 또한, 동일한 메모리를 여러 포인터가 참조할 때 발생할 수 있는 댕글링 포인터(Dangling Pointer, 주인 잃은 포인터) 문제도 존재합니다.

Rust는 소유권 시스템을 통해 이러한 문제를 방지합니다. 여기서 **소유권(Ownership)**이란, 각 값은 오직 하나의 소유자만 가질 수 있으며, 소유자가 범위를 벗어나면 값은 자동으로 해제된다는 것을 뜻합니다.

이러한 시스템은 빌림과 생명주기로 구현되죠.

  • 빌림(Borrowing): 값을 참조할 때는 불변 참조(&T)와 가변 참조(&mut T)를 사용합니다.
  • 생명주기(Lifetime): 참조의 유효 기간을 컴파일 타임에 검사하여 안전성을 보장합니다.
C++ 코드
C++ 코드
Rust 코드
Rust 코드

C++에서는 참조를 통해 빌림을 구현하지만, Rust에서는 불변 참조(&T)로 빌림을 구현하고 소유권을 옮기지 않습니다. 무엇보다 이러한 Rust의 소유권 시스템과 생명주기 규칙은 컴파일 타임에 참조의 유효성을 검사하여 안전성을 보장합니다.

3. 데이터 경합(Race) 방지

Rust의 소유권 시스템과 생명주기 개념은 병렬 처리와 안정성에서 많은 장점을 제공합니다. 특히, Rust의 타입 시스템과 빌림 검사기(Borrow Checker)는 데이터 경합을 방지함으로써 안전한 병렬 프로그래밍을 지원하죠.

데이터 경합이란 여러 스레드가 동시에 같은 데이터를 수정하려 할 때 발생하는 문제입니다. 이런 데이터 경합이 발생하면 예상치 못한 결과나 프로그램 오류가 발생할 수 있습니다. Rust는 컴파일 타임에 데이터 경합을 방지하는 메커니즘을 제공합니다. 이로써 높은 성능과 안정성을 동시에 추구할 수 있습니다.

Rust 코드
Rust 코드

코드 상단의 Arc, Mutex가 보이시나요? Arc(Atomic Reference Counting) 개념은 여러 스레드 간에 소유권을 안전하게 공유할 수 있게 합니다. 또한 Mutex는 상호 배제로 여러 스레드가 동시에 데이터에 접근하지 못하도록 합니다.

이처럼 Rust의 타입 시스템은 Arc와 Mutex를 사용하여 데이터 경합을 방지합니다. Arc는 안전하게 참조를 공유하고, Mutex는 데이터 접근을 동기화하여 경합을 방지합니다.

4. 소유권과 빌림 시스템의 안전성

Rust의 소유권과 빌림 시스템은 데이터 경합을 방지할 뿐만 아니라, 컴파일 타임에 데이터 접근의 안전성을 보장합니다. 이는 런타임에 발생할 수 있는 많은 오류를 사전에 방지합니다.

특히 Rust의 빌림 규칙은 불변 참조(&T)와 가변 참조(&mut T)를 명확하게 구분합니다. 이러한 규칙으로 데이터의 일관성을 유지하고, 데이터 경합을 방지합니다.

Rust에서 불변 참조와 가변 참조는 동시에 존재할 수 없습니다. 이는 데이터의 일관성을 유지하고 안전한 동시성을 보장합니다. 컴파일러 역시 이러한 규칙을 강제하여, 불변 참조와 가변 참조가 동시에 존재하지 않도록 합니다.

Rust 코드
Rust 코드

5. SendSync 트레잇

Rust의 SendSync 트레잇은 병렬 프로그래밍에서 안전성을 보장하는 중요한 역할을 합니다. 만약 타입이 Send 트레잇을 구현하면, 해당 타입의 값이 다른 스레드로 안전하게 이동할 수 있음을 의미합니다. 반면 Sync 트레잇을 구현하면, 해당 타입의 값이 여러 스레드에서 동시에 접근할 수 있죠.

Rust 코드
Rust 코드

위 코드에서 vec![1, 2, 3]Send 트레잇을 구현하므로 스레드 사이를 안전하게 이동할 수 있습니다. 또한 Rust 컴파일러는 SendSync 트레잇으로 스레드 간 데이터 이동과 공유의 안전성을 검사합니다.

6. 안전한 병렬 처리

Rust는 여러 도구와 패턴을 제공해 **안전한 병렬 처리(Fearless Concurrency)**를 실현합니다. 이렇게 개발자가 데이터 경합이나 동시성 버그를 두려워하지 않고, 병렬 코드를 작성할 수 있도록 도와줍니다. Arc, Mutex, RwLock 등이 병렬 프로그래밍에서 데이터의 안전한 공유를 가능하게 해주며, 채널(Channel)이 스레드 사이 통신을 안전하게 처리할 수 있도록 지원합니다.


Rust를 지금 배워도 될까요?

Rust는 배우기 쉬운가요?

Rust는 배우기 쉬운 언어는 아닙니다. 그러나 Rust를 익힌 사람이 많아졌고, 점점 더 늘어나고 있는 걸 보았을 때, 시간을 충분히 들이면 학습할 수 있겠죠. 특히 독특한 소유권 시스템과 생명 주기 규칙이 처음에는 이해하기 어려울 수 있습니다. 그러나 그만큼 개념을 익혔을 때, 안전하고 효율적인 코드를 작성하는 데 큰 도움이 됩니다.

앞으로도 Rust의 인기가 더 높아질까요?

앞서 보았듯 Rust는 이미 개발자들 사이에서 인기를 얻고 있습니다. 그 인기는 계속 높아질 것으로 보입니다. 안정성과 성능, 병렬 처리 특화 덕분에 다양한 산업 분야에서 Rust를 채택하고 있기 때문이죠.

Rust 재단의 적극적인 지원과 활발한 커뮤니티 활동, 여러 빅테크 기업과 제품에서 사용하는 추세 역시 이를 뒷받침합니다. C++을 여전히 많이 사용하는 마이크로소프트를 비롯해서 메타, 나사 등이 Rust를 다양한 로우 레벨 구현 언어로 채택하고 있죠. (참고 글open in new window)

한국에서는 대세로 보기 어렵습니다

그러나 한국에서는 아직 Rust를 대중적으로 널리 쓰고 있지 않습니다. 여전히 Java, JavaScript, Python 등이 주류로 Rust를 채택한 사례는 상대적으로 매우 적습니다. 로우 레벨의 SDK 등을 만드는 기업들도 대부분 Rust보다는 C++을 사용하는 편이고요. 그러니 한국에서 Rust를 배운다 해도 이직에 직접적인 도움이 되기는 어렵다고 생각합니다.

하지만 배워 둔다면 다양한 이득을 얻을 수 있습니다

Rust는 시스템 프로그래밍, 웹 개발, 임베디드 시스템 등 다양한 분야에서 유용하게 사용될 수 있는 언어입니다. 메모리 안전성과 병렬 처리 안전성이 애플리케이션에 있어 아주 중요한 요소이기 때문이기도 하죠.

하지만 웹 개발에서 강점도 있다는 점을 모르시는 분들이 많은데요. Rust는 마찬가지로 다양한 웹 프레임워크 (flosse/rust-web-framework-comparison)open in new window를 가지고 있습니다. Rust를 배우다 보면 병렬 처리에 대한 인사이트, 성능 이슈를 해결할 추가적인 선택지, 안정적인 애플리케이션을 만드는 또다른 방법 등을 익힐 수 있습니다. 또한 클라우드 서비스가 은근슬쩍 자꾸만 비싸지는 이 시점에 유의미한 금전적 의미도 있습니다. 서비스의 트래픽이 늘어날수록 성능 이슈를 해결하는 것만으로 큰 비용을 아낄 수 있으니까요.


마치며

정리해 보겠습니다. Rust는 뛰어난 안정성과 높은 성능, 안전한 병렬 처리를 제공하는 현대적인 시스템 프로그래밍 언어입니다. 실리콘 밸리 주요 기업들로부터 큰 관심을 받고 있으며 앞으로도 인기가 계속 증가할 것으로 예상됩니다. 물론 한국에서는 아직 대중적으로 널리 사용되지 않지만, Rust를 배워둔다면 다양한 분야에서 경쟁력을 갖출 수 있다고 보입니다.

무엇보다 이 언어는 충분히 성숙한 언어입니다. 특히 Rust를 배우는 과정에서 병렬 처리와 안정적인 메모리 관리를 이해할 수 있다면, 여러분도 특별한 개발자로 성장할 수 있을 겁니다.


이찬희 (MarkiiimarK)
Never Stop Learning.