C3 배우기

1 day ago 2

  • C3는 C 언어를 기반으로 하며, 모듈, 연산자 오버로딩, 제네릭, 컴파일 타임 실행 등 고급 기능을 제공함
  • 익숙한 C 문법을 유지하면서, 에러 처리, defer, foreach생산성과 안정성을 강화하는 문법이 탑재됨
  • 선언적 계약(contracts) , 옵셔널 타입과 에러 처리 방식 도입으로 안전성과 명확성이 향상됨
  • 표준 라이브러리와 빌드 시스템 통합, 임시 메모리 할당 등 실용적인 개발 환경이 지원됨
  • 빌드, 프로젝트 생성, 코드 구조 등에서 Zig 언어와 유사성이 있으며, 새로운 언어 설계 실험이 엿보임

C3 개요 및 특징

C3란 무엇인가?

  • C3는 기존 C 언어 위에서 빌드된 언어로, 익숙한 문법 유지와 동시에 C에서는 어려운 모듈 시스템, 연산자 오버로딩, 제네릭, 컴파일 타임 실행, 에러 처리, defer, value methods, 점진적 계약(contracts), 슬라이스, foreach, 다이나믹 타입 지원 등의 기능 제공
  • 네임스페이스를 활용한 모듈 구조로 이름 충돌을 방지함 (abc::Context처럼 명령적 네임스페이스 사용)
  • 주요 목표는 생산성을 높이고 현대적 시스템 프로그래밍 기능을 안전하게 제공함

언어 특징

Hello World 예시

  • C와 문법적으로 유사
  • 함수 선언에 fn 키워드를 명시적으로 사용해야 함
  • 입출력 등 표준 라이브러리 함수가 강력하며, 다양한 타입도 바로 출력 가능

foreach 루프

  • C와 달리 foreach 문법을 기본 지원
  • 참조를 통한 반복문은 변수명 앞에 & 기입(고급 기능)
  • break, continue 지원, 타 언어의 foreach와 유사

while 루프

  • C99 이전에는 선언을 while 조건식 내부에서 못 썼으나, C3에서는 내부 선언이 가능함

enum과 switch문

  • switch문에서 암시적 break 지원(혼재된 암시/명시적 break는 호불호)
  • nextcase 키워드로 명확한 케이스 이동(점프 테이블 구현 간편화) 지원
  • Zig, C 등 기존 언어에서 복잡했던 switch-case 흐름을 간결하게 제어 가능

defer 키워드

  • 스코프 종료 시점에 defer 예약된 구문을 역순으로 실행하여 자원 정리를 안전하게 보장
  • catch, try와 결합된 defer 활용(에러 처리 흐름 제어)

struct와 union

  • struct 내부에 이름/익명 형태의 서브 struct/union 허용, tagged union 패턴 설계가 쉬움
  • 익명(동일 이름 필드 중복)과 이름 충돌의 구분 엄격히 명시

에러 처리 방식

  • ? 기호로 옵셔널 타입 지원, 에러 및 값 옵션을 통합해 편의성 강화
  • catch 키워드로 빈(Optional 없는) 상태/에러 분기 가능
  • Rust, Zig와 달리 에러와 옵션 값 구분이 약함(장점: 단순함, 단점: 취지 명확성 저하)
  • ! 연산자(rethrow)로 예외 전파 가능

계약(Contracts)

  • 함수 전후 조건(Require/Ensure)을 <* .. *> 사이에 작성(컴파일 시 조건 확인)
  • 컴파일 타임 fold 분석까지 지원(정적 분석은 미구현)

struct 메서드

  • 타입 명시 + 점 표기법(Foo.next)으로 연관 메서드 구성, 네임스페이스 있음(프리미티브 포함)
  • 구조체/유니언/enum 등 모든 타입에 메서드 허용

매크로

  • 컴파일 타임 평가 기반 매크로(macro 키워드)
  • $로 컴파일 타임 파라미터, #로 평가 전 전달 구현
  • C 스타일(얽힌 매크로 문제 최소화, AST 안정성 강조, @접두사 체크 등)
  • 타입 리플렉션 및 컴파일 타임 실행을 매크로로 처리

타입 프로퍼티

  • alignof, kindof, extnameof, sizeof, typeid, methodsof, has_tagof, tagof, is_eq, is_ordered, is_substruct 등
  • 메타프로그래밍, 리플렉션에 적합함

Base64/Hex 리터럴

  • b64"..." x"..." 형태로 바이트 시퀀스 직접 선언 가능
  • 내장 매크로 $embed로 대체 필요성(실제론 사용 빈도가 낮음)

프리미티브 타입

  • int, uint, char(무조건 unsigned), bool, float, int128/uint128 등 다양한 기본형
  • iptr, uptr, isz, usz 등 포인터/사이즈 계열의 별도 타입(직관성 약간 떨어짐)
  • C와 달리 bit-size 보장

기타

  • 연산자 오버로딩, 구조체 서브타이핑, 제네릭, 런타임 디스패치, any 타입, 비트필드 구조체(bitstructs) 등 폭 넓은 기능 세트 탑재

실습: C3 경험기

C3 설치

  • 공식 사이트의 프리빌트 바이너리, 직접 소스 빌드 두 가지 지원
  • LLVM, LLD 설치 필요(연결 문제 발생 시 -DLLVM_DIR, -DLLD_DIR CMake 플래그 활용)
  • 일부 배포판의 LLD 라이브러리 미포함 이슈로 바이너리 직접 다운로드 권장
  • C3 컴파일러는 libtinfo 의존성 필요

프로젝트 생성

  • c3c init 명령으로 표준 폴더 구조 생성(LICENSE/README.md/project.json/src 등)
  • Bluild, 빌드 타깃, 소스 설정 등 기반 프로젝트 구성(Zig, Cargo와 유사)
  • 기본 main.c3 파일은 매우 간결(의견: 새로운 유저에게 적합)

계산기 만들기

설계 및 목적

  • 재귀 하강 파서(Recursive Descent Parser) 및 계산기 핵심 로직 구현에 C3의 함수, 입출력, 메모리 관리, 반복문 등 다양한 문법을 실습
  • 문법의 직관성, 실전 생산성 등 우수/불편한 점 직접 파악 목적

입력 처리

  • @pool으로 임시 할당자(tmem) 사용, 스코프 종료 시 자동 메모리 해제(arena allocator)
  • 표준 메모리 관리 방식인 tmem(임시), mem(일반) 지원, 함수 단위 할당자 전달 패턴(Zig과 C의 장점 혼합)
  • main 함수는 반환값 반드시 명시(컴파일러에서 enforced)
  • 리턴값을 무시해도 괜찮은 함수는 @maydiscard 어트리뷰트 표기(악의적 무시 방지)

토크나이저 구현

  • 사용자 입력을 토큰 리스트로 분해
  • C3 표준 라이브러리의 List, foreach 구문, switch-case(nextcase, 암시/명시적 break 조합) 등 다양한 제어문 활용
  • 슬라이스 구문(양 끝 인덱스 모두 포함)과 0 길이 슬라이스 관련 혼란 있음(별도 길이 지정 구문 존재)
  • 임시/일반 할당자 혼합 사용 등 메모리 관리의 투명성과 융통성, Rust 등 타언어 대비 우수함

파서 구현

  • 직접적인 파서 코딩 경험기(생략)

결론 및 종합 의견

  • C3는 전통적인 시스템 언어와 현대적 설계의 접점을 추구
  • Zig, Rust, C를 연구하며, 성과 코드 안정성 양립 언어로 설계됨
  • 모듈성, 안전한 메모리/에러/계약 처리, 강력한 메타프로그래밍, 직관적 빌드 시스템 등 다양한 기능이 두드러짐
  • 학습 곡선은 C 유경험자 기준 점진적으로 진입 가능
  • 언어 서버, IDE 등 생태계 미성숙 및 일부 문법의 호불호 등은 개선 필요
  • 실무 로우레벨/시스템 개발에서 차세대 대안 언어로 주목할만함

Read Entire Article