Zig 0.17과 C로 같은 코드 비교: errdefer, 슬라이스 경계 검사, 강제 에러 처리에서 갈린다
<=off-by-one이 있는 Csum함수는 {1, 2, 3}에서 sum = 7을 출력하고 종료 코드 0으로 끝났으며, clang-Wall -Wextra도 경고하지 않음. 같은 실수를 Zig 슬라이스로 옮기면 debug와 safe 모드에서 index out of bounds: index 3, len 3 panic으로 멈춤- C에서 malloc, strdup, calloc 실패 정리를 하려면 goto 레이블 순서를 할당 순서와 손으로 맞춰야 하지만, Zig는 할당 바로 아래 errdefer를 두면 에러 반환 시 역순으로 풀림
- std.testing.FailingAllocator의 fail_index로 첫째, 둘째, 셋째 할당 실패를 각각 주입해 누수 없는 실패 경로를 테스트했음. 같은 세 경로를 C에서 검증하려면 malloc 래퍼나 외부 도구가 필요함
- Zig는 에러가 반환 타입의 일부라 무시한 호출을 컴파일러가 거부하고 try, catch, if를 강제함. C는 close(), fclose() 반환값을 안 봐도 컴파일이 통과함
- 글쓴이는 C를 여전히 자신이 가장 좋아하는 언어라고 밝히면서도, 새 코드는 C로 쓰지 않겠다고 말함. Zig 0.17과 clang으로 맥에서 실험한 코드가 글에 그대로 실려 있음
Hacker News 의견들
Zig로 C 코드를 컴파일하다 황당한 버그를 만났는데, 순수 Zig로 MUSL을 다시 쓰는 과정에서도 같은 실수가 반복돼서 지금도 main에 남아 있음. 크리티컬한 라이브러리를 다시 쓰면서 그런 실수가 나오면 레드 얼럿급이라고 봄.
Zig 프로젝트는 트렌치코트 입은 여섯 명 정도임. 니가 원하는 걸 3주 만에 우선순위로 처리해 주길 기대하면 안 되지. PR은 올렸어?
블로그에 이슈 링크도 안 걸었더라. codeberg 37402에서 지금 작업 중인 것 같고, 1.0 전이니 치명적이라기보다 성능 회귀 정도로 보임. libc는 다른 구현 링크하면 되는 거 아님?
strchr는 시간복잡도 보장이 없음. 그 동작은 엄밀히 말하면 맞음.
Zig 쓰면 사실상 베타 테스터임. 개발 과정이 매끄럽지 않아서 버그가 잘 새어 나오니까 테스트를 제대로 해야 하고, 큰 프로젝트는 최신 버전을 안 씀. 그래도 재밌고 실용적이라 나는 만족함.
Andrew Kelley가 lobste.rs에서 이 버그에 대해 리뷰에서 판단해서 넘겼고, 그게 맞는 판단이었는지 아직도 모르겠다고 했더라.
Zig가 취미나 학습 프로젝트면 이런 실수도 봐줄 만한데, 실제 돈을 다루는 TigerBeetle 같은 데 쓰이면 둘 다는 못 됨.
이 글 AI 냄새 남. 이 사이트 글마다 'The honest tradeoff' 헤더가 붙어 있고, 홍보하려고 만든 책도 똑같은 슬롭일 듯.
그 헤더가 매번 붙는다는 건 환각임. 증명할 수 없으면 그냥 그렇게 부르는 시대가 됐음.
이 글은 모르겠고 Zig over Rust 글은 확실히 AI가 쓴 티가 남. Pangram도 99% AI라고 하더라.
C에 네이티브 슬라이스가 없는 게 제일 크게 느껴지는 결함임. 위원회가 넣어줄 리도 없고 C는 계속 이 상태일 거임.
C도 포인터랑 길이 주면 슬라이스처럼 쓰는 거 아님? 길이 없는 배열을 괜찮다고 보는 거면 몰라도.
WG14에 기여하면 되고, variably modified type에 span 타입을 직접 만들어 쓰면 꽤 됨. godbolt 예제도 있음.
Zig는 C++만큼 표현력 있는데 암묵적인 동작이 없어서 민감한 코드 리뷰가 쉽고, arena는 C/C++/Rust보다 잘 지원함.
에러 무시 못 하는 건 C에서도 attribute((warn_unused_result))나 C23 [[nodiscard]]로 되는데.
Zig 아직 stable 아님. 예전 프로젝트 만질 때마다 버전 이슈 고치는 게 제일 힘 빠짐.
D랑 Nim은 몇 년 전부터 같은 기능 있었음. 근데 둘 다 기본이 GC라 시스템 프로그래밍 한다는 사람들은 듣자마자 피함.
이런 글은 항상 현대 툴링 안 쓰는 옛날 C랑 비교함. sanitizer, [[nodiscard]], span 타입, 곧 들어올 defer 쓰면 C에서도 다 됨. 개인적으로 goto 에러 처리가 더 읽기 편함.
C에서도 되는데 꾸준히 하려면 규율이 너무 많이 필요하다는 게 Zig의 요점 아님? pit of success 얘기잖아.