-
Rust가 C++를 대체할 수 있을까?카테고리 없음 2020. 11. 7. 11:14
가끔은 Tree 자료 구조가 필요할 때가 있다. 예를 들어, 파일 시스템의 디렉토리 구조를 이름만 가지고 추적하고자 할 때가 그런데, 각 노드(즉, directory)는 list인데, leaf (즉, 파일) 혹은 자식 노드를 (즉, subdirectory) 원소로 가지는 list로 나타낼 수가 있다. 물론, 실제 linux 파일 시스템도 크게 다르진 않아서, 파일/디렉토리를 나타낼 때 이름 대신, 그 inode를 (디스크 상의 주소?) 사용한다는 것이 다르다고 할까.
.Net에선 어떤지 모르겠지만, C++ STL에선 linked list, set, queue, dictionary, heap 같은 자료 구조들은 다 지원하면서 유일하게도 tree는 없다. 적어도 red-black tree 같은 전형적인 binary tree는 지원할 만도 한데... 하지만 없다. 내 생각엔 사용 빈도가 그리 많지 않아서 그렇지 않을까 싶다.
뭐... C/C++로 구현하는 것이 그리 어렵진 않을 것이다.
여기서부터 실질적인 이야기를 하자면, red-black tree를 C로 구현한다고 하자. 아마 한방에 제대로 만들기는 힘들 것이다. Search/insert/delete 함수를 구현하고 나서, 디버깅을 해 보면 아마도 제대로 동작하지 않거나 (예를 들어, 분명 insert를 했는데 insert가 되지 않는다든지) 어딘가에서 segment fault가 생길 것이다. 물론, 몇 번의 디버깅을 거친 후에 완성할 수 있겠지만, 아무튼...
여기서의 문제는 포인터 사용에 관한 것으로, 제대로 된 주소가 아닌 값이나 엉뚱한 주소를 포인터 변수에 저장하기 때문일텐데, 꽤 잡기 어려운 문제이다. 하지만, Rust에선 이를 compile-time에 잡아낸다고 하는데, 즉 이 경우 컴파일이 되면 runtime error가 발생하지 않는다는 것이다 (참고로, Haskell은 이보다 좀 더 대단한데, 로직이 잘못되지 않은 한 99%(?) 컴파일이 되면 runtime에선 문제가 생기지 않는다. ^^) 대신 pointer를 사용할 땐 규칙이 있다, 모든 포인터는 그 메모리의 owner가 누군지 컴파일러가 추적할 수 있어야 한다는 것인데... 이 규칙 때문에 Rust는 참 어렵다고 말들을 많이 한다.
개발자를 믿지 못하겠기에 컴파일러가 대신 복잡한(?) 규칙을 가지게 되었고, 그 결과 포인터 관련한 프로그램은 복잡도가 증가하는데(C++도 가뜩이나 복잡한데 그 C++에 비해 두 배 정도로 코드가 커진다고 할까)... 여기서 갈등이 시작된다. Memory safety는 좋은데 대신 늘어나는 complexity, 그리고 learning-curve는 과연 그만한 가치가 있는 것인가.Rust가 과연 C++를 대체할 수 있을까? 미천한 내 생각으로... 난 아니라고 말하고 싶다. ^^;
참고: https://medium.com/@JoeKreydt/rusts-complexity-problem-a-warning-55c3a6484038