C가 최고다 (2025)
(sqlite.org)- SQLite는 2000년부터 C 언어로 구현된 경량 데이터베이스 엔진으로, 다른 언어로 다시 작성할 계획이 없음
- C는 성능, 호환성, 의존성 최소화, 안정성 측면에서 SQLite에 가장 적합한 언어로 평가됨
- 객체지향 언어(C++, Java 등)는 언어 간 호출 제약이 크고, 절차적 접근이 오히려 단순하고 빠를 수 있음
- Rust나 Go 같은 ‘안전한 언어’ 는 아직 성숙하지 않았고, SQLite의 품질 전략(예: 100% 분기 테스트, OOM 복구)에 부합하지 않음
- 향후 Rust로의 이식 가능성은 열려 있으나, 성숙도·호환성·성능·도구 지원 등 여러 조건이 충족되어야 함
1. C가 최선인 이유
- SQLite는 2000년 5월 29일 처음부터 일반 C 언어로 구현되었으며, 현재까지도 다른 언어로의 전환 계획이 없음
- C가 SQLite 구현에 적합한 이유로 성능, 호환성, 저의존성, 안정성을 제시
1.1 성능
- SQLite는 집약적으로 사용되는 저수준 라이브러리로서 빠른 속도가 필수
- 예시로 “Internal Versus External BLOBs”, “35% Faster Than The Filesystem” 문서에서 성능 입증
- C는 ‘이식 가능한 어셈블리 언어’ 로 불릴 만큼 하드웨어에 가까운 제어를 제공하면서도 플랫폼 간 이식성 유지
- 다른 언어들이 “C만큼 빠르다”고 주장하지만, C보다 빠르다고 주장하는 언어는 없음
1.2 호환성
- 거의 모든 시스템이 C로 작성된 라이브러리 호출 기능을 제공
- 예를 들어 Android는 Java 애플리케이션에서 SQLite를 어댑터를 통해 호출 가능
- 만약 SQLite가 Java로 작성되었다면, Objective-C나 Swift 기반 iPhone 앱에서는 사용 불가했을 것
1.3 저의존성
- C로 작성된 라이브러리는 런타임 의존성이 매우 적음
- 최소 구성에서 SQLite는 표준 C 라이브러리의 다음 함수만 필요
- memcmp(), memcpy(), memmove(), memset(), strcmp(), strlen(), strncmp()
- 완전 빌드에서도 malloc(), free(), 파일 입출력 정도만 사용
- 반면 현대 언어들은 수 MB 규모의 런타임과 수천 개 인터페이스를 요구
1.4 안정성
- C는 오래되고 변화가 적은 언어로, 명확하고 예측 가능한 동작을 제공
- SQLite처럼 작고 빠르며 신뢰성 있는 데이터베이스 엔진을 개발할 때, 언어 사양이 자주 바뀌지 않는 것이 중요
2. 객체지향 언어로 작성되지 않은 이유
-
일부 개발자는 복잡한 시스템을 객체지향 언어로만 구현할 수 있다고 생각하지만, SQLite는 그렇지 않음
-
C++이나 Java로 작성된 라이브러리는 동일 언어로 작성된 애플리케이션에서만 사용 가능
- 반면 C 라이브러리는 거의 모든 언어에서 호출 가능
-
객체지향은 디자인 패턴이지 언어 자체가 아님, C에서도 객체지향적 구조 구현 가능
-
객체지향이 항상 최선은 아니며, 절차적 코드가 더 단순하고 유지보수 및 성능 면에서 유리한 경우도 있음
-
SQLite 개발 초기(2000년대 초)에는 Java가 미성숙했고, C++은 컴파일러 간 호환성 문제가 심각했음
- 당시 C가 명백히 더 나은 선택이었으며, 현재도 재작성 이점이 거의 없음
3. ‘안전한 언어’로 작성되지 않은 이유
- 최근 Rust, Go 같은 ‘안전한 언어’ 가 주목받지만, SQLite는 여전히 C로 유지됨
- SQLite 초기 10년 동안 안전한 언어가 존재하지 않았음
- Go나 Rust로 다시 작성할 수는 있으나, 새로운 버그 발생과 속도 저하 위험 존재
- 안전한 언어는 배열 경계 검사 등 추가 분기(branch) 를 삽입
- 올바른 코드에서는 해당 분기가 실행되지 않아, 100% 분기 테스트 불가능
- 대부분의 안전한 언어는 메모리 부족(OOM) 시 프로그램을 중단
- SQLite는 OOM에서도 정상 복구하도록 설계되어 있어, 이 동작과 충돌
- 기존 안전 언어들은 모두 새롭고 빠르게 변화 중
- SQLite는 오래되고 안정적인 언어를 선호
4. Rust로의 이식 가능성
- SQLite가 Rust로 재작성될 가능성은 존재하지만, Go로의 이식은 거의 불가능
- 이유: Go는 assert()를 싫어함
- Rust로 이식되기 위한 전제 조건
- Rust가 더 성숙해지고, 변화 속도가 느려져 ‘오래되고 안정적인 언어’ 가 될 것
- Rust가 모든 언어에서 호출 가능한 범용 라이브러리를 생성할 수 있을 것
- 운영체제가 없는 임베디드 장치에서도 동작 가능한 객체 코드를 생성할 것
- 100% 분기 커버리지 테스트를 지원하는 도구 체계를 갖출 것
- OOM 복구 메커니즘을 제공할 것
- C 수준의 성능 손실 없는 구현을 입증할 것
- Rust가 위 조건을 충족한다고 생각하는 개발자는 SQLite 팀에 직접 연락해 논의 가능
5. 결론
- SQLite는 작고, 빠르고, 신뢰성 있는 데이터베이스 엔진으로, C 언어의 특성이 그 목표에 부합
- 객체지향이나 안전한 언어로의 전환은 호환성, 성능, 품질 관리 측면에서 실익이 없음
- C의 단순함과 안정성이 SQLite의 장기적 유지보수와 신뢰성을 뒷받침함
compact한 상황이라면 c, c++, rust를 대체할 언어는 없습니다. 구조체 또는 map에 비트단위로 오버풀로우나 해킹을 염려해서 개발을 하는것을 공감할 개발자들이 별로 없을뿐이죠
다양한 개발 상황에 , 적합한 언어를 쓰는, 그런 판단을 할 수 있는게 중요하지, 특정 언어가 항상 좋다는 것처럼, 저런 제목을 다는건 , 생각하는 수준이 중졸이다...
C의 가장 큰 장점은 '컴퓨터는 비트열'이라는 본질에 그대로 닿아있기 때문이라고 생각합니다. C의 단순한 철학과 과격한 reinterprete casting으로 사용자가 거의 항상 어떤 기계어로 번역될지 알 수 있다는 매력이 있죠. C라서 모든 언어에서 호출 가능한것이 아니라, ABI가 호출 가능한것이고, C에선 단지 입출력이 어떤 비트열인가를 예측 가능하기 (혹은 해야하기) 때문이겠죠. 항상 구현가능성에 대해 논의할때도, 이것이 튜링머신에서 불가한가 혹은 지금 쓰는 언어나 프레임워크에서 불가한가의 구분이 중요하다고 생각이 듭니다.
Hacker News 의견들
-
모든 프로젝트나 프로그래머가 Rust나 Zig를 쓰지 않는 이유를 굳이 정당화할 필요는 없다고 생각함
Hacker News나 다른 플랫폼에서 이 언어들이 과도하게 밀어붙여지는 경향이 있음
C로 충분히 좋은 결과를 내고 있고, 사용자들도 만족한다면 외부에서 왈가왈부할 이유가 없음- 새 언어들이 주목받는 건 당연한 일임
기술 발전에 관심 있는 사람들이 새로운 언어의 가능성을 탐구하는 건 자연스러운 흐름임
다만 외부에서 의견을 말할 자유는 있지만, 프로젝트가 들을 의무는 없음 - Rust의 설계 철학과 최근 Linux 커널의 Rust 버그 사례를 보면, Rust가 완벽한 해결책은 아님
Rust는 버그 노출을 줄이지만, 여전히 같은 종류의 버그가 존재함
C 개발자는 경쟁 조건에 더 민감하게 반응하는 경향이 있고, Rust는 ‘안전’ 주석에 과신할 위험이 있음
또한 Rust에서는 수정이 단순하지 않아 리팩터링 부담이 커질 수 있음
결국 Rust는 흥미로운 언어지만 만능은 아니며, 강요해서는 안 된다고 생각함 - 요즘은 오히려 OOP에 대한 회의론이 커지고 있음
Rust나 Zig 같은 언어는 전통적인 객체지향 패턴을 벗어나려는 의도를 갖고 있음
OOP는 한때 ‘깨달음’을 주는 개념적 틀로 매력적이었지만, 실제로는 복잡성을 늘리고 모듈성을 해치는 경우가 많음 - Rust가 모든 면에서 더 낫고 버그를 줄여준다면 사람들이 칭찬하는 게 이상하지 않음
손드릴 대신 전동드릴을 쓰는 게 당연한 것처럼, 더 나은 도구가 있으면 그걸 쓰는 게 자연스러움 - 최근 미국 정부가 메모리 안전하지 않은 언어(C 등) 사용을 중단하라고 권고했음
하지만 안전한 C 코드를 작성할 수 있는 도구와 교육도 충분히 발전할 필요가 있음
- 새 언어들이 주목받는 건 당연한 일임
-
나는 꽤 진지한 Rustacean이지만, 모든 프로젝트를 Rust로 다시 쓰는 건 합리적이지 않다고 생각함
이미 잘 검증된 C 프로젝트를 Rust로 옮기면 단기적으로는 오히려 버그가 늘어날 가능성이 큼
다만 일부는 Rust로의 재작성에 도전 중이며, 예를 들어 Limbo: SQLite를 Rust로 완전 재작성한 프로젝트가 있음- Limbo는 흥미롭지만 멀티프로세스 접근 불가라는 제약이 큼
SQLite의 주요 장점 중 하나가 여러 프로세스에서 동시에 접근 가능한 점인데, 이게 빠지면 활용 범위가 좁아짐 - Rust 개발자들이 굳이 SQLite의 승인을 기다릴 필요는 없음
직접 새 버전을 만들어보고 성공 여부를 실험하면 됨 - 개인적으로는 SQLite를 포팅하기보다 Rust로 새로운 임베디드 DB를 만드는 게 더 합리적이라 생각함
- Limbo가 어떻게 발전할지 지켜볼 예정임
- Limbo는 흥미롭지만 멀티프로세스 접근 불가라는 제약이 큼
-
RediSearch를 Rust로 마이그레이션한 경험이 있음
이는 최근 CVE 취약점이 많았기 때문이었음
SQLite에는 이런 문제가 없다면 Rust로 옮길 이유가 약함
Rust의 강점과 한계를 이해하려면 수십 년의 시간이 필요할 것 같음
특히 GUI 애플리케이션에서 Rust의 효용은 아직 불분명함- C의 안정성과 ‘지루함’은 수십 년의 시행착오 끝에 얻은 결과임
Rust가 같은 수준의 신뢰를 얻으려면 2040년쯤은 되어야 할지도 모름 - SQLite 같은 시스템에는 Ada/SPARK 같은 언어가 더 적합할 수도 있음
- C의 안정성과 ‘지루함’은 수십 년의 시행착오 끝에 얻은 결과임
-
Linus가 언급했듯이, Rust에는 OOM(Out of Memory) 복구 메커니즘이 필요함
관련 내용은 LKML 토론 링크에서 볼 수 있음- 하지만 Rust의 언어 기능 자체는 기본적으로 스택 할당 중심이라 malloc을 직접 호출하지 않음
임베디드나 커널 코드에서는 할당 기능을 완전히 끌 수도 있음
즉, Rust는 이미 메모리 제어권을 완전히 제공함 - (여담) 해당 페이지의 CSS를 개선하는 코드도 공유됨
- Linus의 지적은 맞지만, 본인 진영의 문제도 정리할 필요가 있음
- 하지만 Rust의 언어 기능 자체는 기본적으로 스택 할당 중심이라 malloc을 직접 호출하지 않음
-
“C보다 빠른 범용 언어는 없다”는 주장은 개발자 시간을 무시한 단편적 비교임
C로 5시간 걸려 4초짜리 프로그램을 만드는 것보다, 다른 언어로 5분 만에 5초짜리를 만드는 게 현실적일 수 있음- 하지만 SQLite처럼 사용자 CPU 시간이 압도적으로 많은 소프트웨어에서는 C의 효율이 훨씬 중요함
사용자 수가 많을수록 미세한 속도 차이도 누적 가치가 큼 - 결국 사용자 시간을 중시한다면, C의 성능 최적화는 여전히 큰 의미가 있음
- 하지만 SQLite처럼 사용자 CPU 시간이 압도적으로 많은 소프트웨어에서는 C의 효율이 훨씬 중요함
-
Rust가 ‘지루하고 안정적인’ 언어가 되려면 아직 멀었음
C는 보수적인 위원회가 관리하며 호환성을 철저히 지키는 반면, Rust는 문제 해결을 위해 호환성보다 혁신을 우선함- Rust는 언어 자체는 가끔 호환성을 깨지만, 도구 체계는 안정적임
예전 버전의 코드를 새 컴파일러로도 계속 빌드할 수 있음 - Rust는 구버전 코드를 구버전 컴파일러로 자동 처리해 레거시 부담을 줄이는 방식을 택함
이는 C++처럼 과거 기능을 계속 짊어지는 접근보다 낫다고 생각함 - C의 보수성은 ‘이상한’ 게 아니라 안정성의 상징임
- C는 원래 한 명의 강한 의견을 가진 사람이 설계했기 때문에 명확한 방향성이 있었음
반면 C++이나 Common Lisp처럼 위원회 설계 언어는 복잡성이 커졌음
Rust도 규모가 커서 임베디드나 핵심 시스템에는 신중히 써야 함 - Rust도 언젠가는 안정기에 접어들 수 있을 것 같음
- Rust는 언어 자체는 가끔 호환성을 깨지만, 도구 체계는 안정적임
-
“잘 작동하는 걸 굳이 깨뜨리지 말자”는 태도에 공감함
언어 발전의 역사는 문제를 해결하려다 새로운 복잡성을 만드는 과정의 반복 같음- Mozilla가 Rust를 만든 이유는 C++의 문제 때문이지만, Rust는 단순히 C++의 대체물이 아님
C는 “Worse is Better” 철학의 대표 사례로, 단순함 덕분에 수십 년간 성공했음
Rust는 반대로 “Right Thing™”을 지향함
오늘날 대부분의 환경에서 직접 구현 부담이 줄었기 때문에, 이제는 더 나은 선택이 될 수 있음
하지만 이미 성공한 프로젝트를 굳이 옮길 필요는 없음
새 프로젝트라면 Rust가 더 나은 선택일 가능성이 큼
- Mozilla가 Rust를 만든 이유는 C++의 문제 때문이지만, Rust는 단순히 C++의 대체물이 아님
-
C의 단순함과 안정성은 과소평가된 장점임
언어 자체를 계속 바꾸기보다 표준 라이브러리나 생태계를 다듬는 게 낫다고 생각함- 다만 C에도 여전히 UB(정의되지 않은 동작) 이 많아 주의가 필요함
단순함뿐 아니라 결정적 동작 보장도 중요함 - Clojure처럼 단순하고 우아하며 안정적인 언어를 선호함
- C는 새로운 기능을 추가하더라도 대부분 논란 없는 실용적 개선임
예를 들어 designated initializer, compound literal, alignas, memset_explicit 같은 기능들이 마음에 듦
- 다만 C에도 여전히 UB(정의되지 않은 동작) 이 많아 주의가 필요함
-
개인적으로 C가 여전히 최고라고 생각함
Rust는 좋은 아이디어가 많지만 단점도 뚜렷한 언어임
아직은 Rust의 문제점을 냉정하게 논의하기 어려운 분위기임- Rust의 단점이 무엇인지 구체적으로 지적하면 논의가 더 생산적일 것 같음
예를 들어 학습 곡선이나 패키징 복잡성 같은 부분이 있을 수 있음 - “Rust는 끔찍한 언어”라는 주장에는 구체적 근거가 필요함
- Rust의 단점이 무엇인지 구체적으로 지적하면 논의가 더 생산적일 것 같음
-
“모든 시스템이 C 라이브러리를 호출할 수 있다”는 말은 이제 사실이 아님
Rust나 Zig도 이 요구사항을 충족함
다만 Rust의 표준 라이브러리는 OOM 시 복구 대신 패닉하는 경우가 많고, 문서화도 부족함- Rust와 Zig는 명시적으로
extern "C"나export를 써야 C ABI 호환이 됨
그렇지 않으면 ABI가 정의되지 않아 오히려 C++보다 불안정할 수 있음
특히 Rust crate를 배포하는 리눅스 배포판에서는 이 문제가 더 커질 수 있음
- Rust와 Zig는 명시적으로