우리 문명을 떠받치고 있는 프로그래밍 언어는 뭐니뭐니 해도 C언어이다. 수많은 언어들이 생겨났어도 하드웨어 레벨의 리눅스 커널은 C언어를 고수하고 있다.
C언어를 뛰어넘어 대체할 언어로 여러 언어가 있지만 하나같이 못마땅했다.
C++은 온갖 개념들을 잡탕으로 섞어 놓은 괴물덩어리라 패스.
최근 각광을 받고 있는 Rust는 오너쉽과 라이프타임이라는 정신나간 제약사항 때문에 발생하는 극심한 러닝커브로 패스. 코드가 불필요하게 장황하다.
Odin과 Zig가 좀더 현대적인 C를 지향하지만 신택스가 생경하다. Zig 커뮤니티가 좀 크고 훌륭한 개념이 도입되었지만, 신택스가 상당히 낯설어 아쉬운 면이 많았다. 여태까지는 Zig가 그나마 가장 C에 친화적이었다.
하지만 더이상 고민할 필요가 없게 됐다. C3가 아주 편안하게 차세대 C언어를 제공해 주기 때문이다.
에러 처리를 비교해 보자. 요즘 대세는 에러를 Exception으로 처리해서 코드를 복잡하게 하지 말고, 리턴값에 옵셔널로 처리하는 것이다.
Rust - 에러 유니온
use std::fs::File;
use std::io::{self, Read};
fn read_file(path: &str) -> Result<String, io::Error> {
let mut file = File::open(path)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
Ok(contents)
}
fn main() {
match read_file("data.txt") {
Ok(contents) => println!("File contents: {}", contents),
Err(e) => eprintln!("Error: {}", e),
}
}
함수의 리턴 타입을 Result<String, io::Error>으로 정서 옵셔널 함수임을 표시했다. 함수 호출시 끝에 ?를 붙여 에러 발생이 될 수 있음을 표시했다.
리턴받은 값이 Ok(contrnts)냐 Err(e)냐로 match {}를 써서 처리했다.
눈여겨 볼것은 메모리 해제와 파일 닫기를 하지 않아도 된다는 것이다. 전반적인 코딩 스타일은 너무 생경하고 어렵다.
Zig 에러처리
const std = @import("std");
fn readFile(allocator: std.mem.Allocator, path: []const u8) ![]u8 {
const file = try std.fs.cwd().openFile(path, .{});
defer file.close();
const contents = try file.readToEndAlloc(allocator, 1024 * 1024);
return contents;
}
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
const contents = readFile(allocator, "data.txt") catch |err| {
std.debug.print("Error: {}\n", .{err});
return;
};
defer allocator.free(contents);
std.debug.print("File contents: {s}\n", .{contents});
}
함수의 리턴타입이 ![]u8로 에러가 옵셔널로 올수 있음을 표시했고 에러가능한 함수 호출시 try를 썼다.
리턴받는 쪽에서 catch |err|로 에러를 잡아냈다.
메모리 할당자를 명시적으로 표현해서 코드가 상당 번거롭다.
신택스가 전반적으로 생경하고 이질적이다.
C3의 간명한 에러처리
import std::io;
fn String? read_file(String path)
{
File? file = file::open(path, "r");
if (catch err = file)
{
return io::FILE_NOT_FOUND?;
}
String? contents = file.read_all();
file.close();
return contents;
}
fn void main()
{
String? result = read_file("data.txt");
if (catch err = result)
{
io::printfn("Error: %s", err);
return;
}
io::printfn("File contents: %s", result);
}
옵셔널 에러를 ?하나로 깔끔하게 처리했다.
리턴 받는 쪽에서 catch로 에러를 처리했다.
전체코드가 너무나도 간명하다.
Rust, Zig, C3의 컴파일 타임 메타프로그래밍을 비교
Rust - 매크로와 const 함수
Rust는 주로 매크로 시스템과 const 함수를 통해 컴파일 타임 처리를 수행한다.
// const 함수 - 컴파일 타임에 실행 가능
const fn factorial(n: u32) -> u32 {
match n {
0 => 1,
_ => n * factorial(n - 1)
}
}
// 컴파일 타임에 계산됨
const RESULT: u32 = factorial(5); // 120
// 매크로 예제
macro_rules! create_function {
($func_name:ident) => {
fn $func_name() {
println!("함수 {}가 호출됨", stringify!($func_name));
}
};
}
create_function!(hello); // 컴파일 타임에 함수 생성
타입 시스템이 강력하지만, 매크로 문법이 일반 코드와 다소 이질적이다.
Zig - comptime 키워드
Zig는 `comptime` 키워드로 일반 코드를 컴파일 타임에 실행할 수 있다.
// comptime으로 컴파일 타임 계산
fn fibonacci(n: u32) u32 {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
const result = comptime fibonacci(10); // 컴파일 타임에 계산
// 타입도 comptime 값으로 전달 가능
fn Matrix(comptime T: type, comptime rows: usize, comptime cols: usize) type {
return [rows][cols]T;
}
const IntMatrix = Matrix(i32, 3, 3); // 컴파일 타임에 타입 생성
// comptime 반복문
fn generateArray() [5]u32 {
var arr: [5]u32 = undefined;
comptime var i = 0;
inline while (i < 5) : (i += 1) {
arr[i] = i * i;
}
return arr;
}
일반 코드와 동일한 문법으로 컴파일 타임 처리를 작성할 수 있어 매우 직관적이다.
C3 - $ 접두사와 매크로
C3는 `$` 접두사와 매크로 시스템을 통해 컴파일 타임 처리를 제공한다.
// $ 접두사로 컴파일 타임 변수
const $SIZE = 10;
int[SIZE] array; // 컴파일 타임에 크기 결정
// 컴파일 타임 if
fn void process(int value) {
$if $defined(DEBUG):
io::printn("디버그: value = %d", value);
$endif
}
// 컴파일 타임 foreach
macro generate_getters($Type) {
$foreach ($field : $Type.fields):
fn $field.type $Type.get_$field.name(&self) {
return self.$field.name;
}
$endforeach
}
struct Person {
String name;
int age;
}
generate_getters(Person); // 컴파일 타임에 getter 생성
C 문법에 가까우면서도 강력한 메타프로그래밍 기능을 제공한다. 코드의 명확성 면에서 C3가 확실히 직관적이고 강력하다.
'병상일기' 카테고리의 다른 글
| 구형 갤럭시 폰을 가정용 리눅스 서버로 쓰는 법 (Termux) (0) | 2025.11.28 |
|---|---|
| 텍스트로서의 코란 - 횡설수설 (0) | 2025.11.06 |
| 국내 척수손상 재생신약 KDS2010 (IBS) (0) | 2025.10.17 |
| ARC-EX기기를 이용한 손기능 개선 (척수손상 사지마비) (0) | 2025.09.15 |
| 사업화 아이디어: 한글 이름 AI 서비스 (0) | 2025.09.02 |