블로그

SafeC 1.0.0-beta-7 릴리스

SafeC 1.0.0-beta-7이 2026-10-27에 릴리스되었습니다. 프리릴리스이며, 언어와 표준 라이브러리는 아직 빠르게 바뀌고 있습니다.

지금까지 가장 큰 릴리스입니다. 1.0.0-beta-6 이후 병합된 풀 리퀘스트 #51부터 #88까지가 모두 들어 있습니다. 변경이 병합되는 동안 기록해 온 다음 릴리스 미리 보기에 영역별 설명이 더 자세히 있고, 변경 내역은 개별 시그니처 수준까지 모든 변경을 나열합니다.

이 릴리스를 그대로 설치하려면:

bash
curl -fsSL https://raw.githubusercontent.com/safec-org/SafeC/main/install.sh | bash -s -- --version=v1.0.0-beta-7
powershell
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/safec-org/SafeC/main/install.ps1))) -Version v1.0.0-beta-7

주요 변경 사항

  • 웹 스택 (#57): std/http는 라우터와 미들웨어, 정적 파일, 쿠키, multipart 폼, server-sent events, WebSocket을 갖춘 keep-alive 서버이며, 리디렉션을 따라가고 gzip을 푸는 URL 클라이언트도 있습니다. std/encoding/url과 std/encoding/deflate가 함께 추가되었고, std/wasm은 DOM과 브라우저 API를 모두 다룹니다.
  • HTTPS (#66): std/tls는 운영체제의 TLS(OpenSSL, SChannel, Secure Transport)를 쓰고, 없으면 SafeC로 작성한 TLS 1.3으로 대체합니다. std/http는 https://와 wss://를 지원합니다.
  • 비동기 (#61): std/async는 Rust의 Future / Poll / Waker 모델을 goto 상태 머신으로 옮겼습니다. 타이머, 조합기, 채널, 힙을 쓰지 않는 LocalExecutor, 멀티스레드 ThreadPool, 비동기 TCP를 제공합니다.
  • GUI 툴킷 (#63, #65): std/gui는 TrueType 텍스트를 그리는 안티에일리어싱 벡터 캔버스, 위젯 툴킷, 여러 창을 다루는 GuiApp을 X11, Wayland, Win32, Cocoa, 웹에서 제공하며, GL ES, Metal, D3D11 프레젠터가 있습니다.
  • 오디오와 MIDI (#59): std/audio는 ALSA, JACK, Core Audio, WASAPI, Web Audio 위의 하나의 콜백 API이며, 모든 플랫폼에서 MIDI를 지원합니다.
  • safeguard doc과 safeguard publish (#69): 어떤 패키지든 rustdoc 스타일의 API 레퍼런스를 만들고(std의 레퍼런스는 /api/), CI, 릴리스 아카이브, Pages 문서와 함께 라이브러리를 배포할 수 있습니다.
  • scc (#70): SafeC로 작성한 SafeC 컴파일러로, WebAssembly를 출력하고 자기 자신을 바이트 단위로 똑같이 재현합니다. 브라우저에서 플레이그라운드를 실행하는 것이 scc입니다.
  • safeguard 패키지 (#51, #55): C, C++, Objective-C 패키지와 의존성, 라이브러리 헤더, Windows DLL, 앱 번들을 지원합니다. 빌드는 프로젝트가 쓰는 std 모듈만 해당 시스템 라이브러리와 함께 링크합니다.
  • Vulkan과 WebGPU에서의 ML (#54): CUDA, ROCm, Metal에 더해 SPIR-V(Vulkan)와 WebGPU용 std/ml 텐서 디바이스가 추가되었습니다.
  • 섹션 단위로 미리 빌드된 std (#56): 릴리스에 플랫폼별로 컴파일된 std가 섹션마다 하나의 아카이브로 들어 있고, install.sh --std=... / install.ps1 -Std ...로 고릅니다. 릴리스 바이너리는 macOS 11, glibc 2.25 이상에서 실행됩니다.
  • 버전 확인: safec --version과 새로 추가된 safeguard --version이 모두 1.0.0-beta-7을 출력합니다(#85).
  • 수정 사항: 가변 인자 호출에서 bool / char / short를 int로 승격하고, const &T 필드 쓰기, -> 탈출, 컨테이너 원소 참조에 관한 안전성 검사의 빈틈을 막았습니다. 모든 컨테이너가 원소를 drop하고, Typedef** x 지역 변수 선언을 파싱하며, 수명 분석이 const &R T를 const 참조로 다루고 식의 임시 값을 전체 식 끝에서 끝냅니다. Windows와 macOS CI가 통과합니다(#52, #53, #64, #68, #71–#75, #78, #79, #82–#84).
  • 컴파일러와 safeguard 수정 (#86, #87): __VA_ARGS__가 모든 인자로 펼쳐지고, #line이 동작하며, "release" / "acq_rel"을 준 atomic_cas가 유효합니다. libc 헤더를 두 번 인클루드해도 문제가 없고, safeguard가 Linux에서 libm을 링크하며, BST<..., struct>에 많이 삽입하는 파일이 수십 초가 아니라 1초 안에 컴파일됩니다. 증분 캐시에서 가져온 파일도 경고를 다시 출력합니다.

호환성을 깨는 변경

아래의 모든 변경은 컴파일러가 영향을 받는 줄마다 보고합니다 — 잘못된 인자 개수나 타입, 선언 위치를 가리키는 소유권 오류, 또는 찾을 수 없는 헤더. 변경 내역에 적힌 경우를 빼면 동작이 조용히 바뀌는 일은 없습니다.

  • std API는 void*나 포인터 + 길이 쌍 대신 슬라이스를 받습니다 (#76, #80, #81). 버퍼는 []T / []const T이고, 콜백 컨텍스트는 ?&Erased에 저장되는 타입 있는 ?&T이며, std 어디에도 void*가 남아 있지 않습니다. 할당자는 ?&heap unsigned char를 돌려주고, 오디오와 MIDI 콜백 컨텍스트는 Send + Sync여야 합니다.
  • 컴파일러가 강제하는 Drop, Send, Sync (#77). Drop 타입의 값은 모든 경로에서 정확히 한 번 drop되거나 이동되어야 합니다. spawn, 채널, 스레드 풀은 공유하거나 이동해도 안전한 데이터만 받습니다.
  • 컨테이너가 원소를 소유합니다 (#83). clear(), drop(), 키 덮어쓰기가 값을 drop하므로, 그 전에 값을 직접 해제하지 마세요.
  • std 헤더는 <std/...>로만 인클루드합니다 (#83). safeguard가 더 이상 std/ 자체를 인클루드 경로에 넣지 않으므로, 맨 이름의 <math.h>는 C 라이브러리의 헤더이고 #include <io.h>는 #include <std/io.h>로 바꿔야 합니다.

마이그레이션

  1. 버퍼: 슬라이스를 넘깁니다 — f.read(buf[..]), w.write(buf[0..n]), sha256(bytes, digest[..]), str_copy(dst[..], src). safe_memcpy는 이제 원소 개수를 셉니다. 타입: 슬라이스, 읽기 전용 슬라이스, 옵셔널 슬라이스를 참고하세요.
  2. 소유권: Drop 타입의 값을 만든 직후 defer v.drop();을 추가하거나(또는 모든 경로에서 해제하고), 데이터는 thread_spawn으로 스레드에 이동하거나 Mutex<T>로 공유합니다. 소유권과 Drop과 스레드 안전성을 참고하세요.
  3. 컨테이너: 컨테이너만 drop합니다 — m.drop() 앞의 m.foreach(free_value) 같은 코드를 지웁니다. 컬렉션: 컨테이너가 원소를 소유합니다를 참고하세요.
  4. 인클루드: #include <io.h> / "prelude.h"를 #include <std/io.h> / <std/prelude.h>로 바꿉니다. 표준 라이브러리 모듈의 std 인클루드를 참고하세요.
  5. 사용자 정의 할당자와 해셔: alloc / dealloc을 ?&heap unsigned char로, 사용자 Hasher를 슬라이스 시그니처로 바꿉니다.

전후 비교 표 전체와 실행할 수 있는 예제 두 개는 다음 릴리스 미리 보기: 마이그레이션에 있고, 변경 내역의 Breaking changes 절은 바뀐 시그니처를 모듈별로 모두 나열합니다.

업그레이드

설치 스크립트를 다시 실행하면 기존 설치를 그 자리에서 업그레이드합니다(프리릴리스를 포함한 최신 릴리스를 설치하며, 이 릴리스로 고정하려면 버전을 넘깁니다):

bash
curl -fsSL https://raw.githubusercontent.com/safec-org/SafeC/main/install.sh | bash -s -- --version=v1.0.0-beta-7
powershell
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/safec-org/SafeC/main/install.ps1))) -Version v1.0.0-beta-7

쓰던 std 섹션은 --std=... / -Std ...로 유지하고, 나중에 --std=+<섹션>으로 추가할 수 있습니다. 모든 옵션은 설치에 있습니다. 그다음 설치된 버전을 확인합니다:

bash
safec --version       # safec 1.0.0-beta-7
safeguard --version   # safeguard 1.0.0-beta-7

예전 std로 컴파일된 것이 링크되지 않도록 프로젝트를 처음부터 다시 빌드하세요(safeguard clean && safeguard build).

알려진 문제

1.0.0-beta-7에 알려진 문제입니다.

  • GPU 백엔드는 컴파일만 검증되었습니다. std/ml의 CUDA, ROCm, Metal, Vulkan, WebGPU 경로와 std/gui의 GPU 프레젠터는 모든 플랫폼의 CI에서 컴파일되지만, 이번 릴리스는 GPU 하드웨어에서 실행해 보지 않았습니다.

다른 문제를 만나면 이슈를 열어 주세요.

풀 리퀘스트

풀 리퀘스트 제목은 영어 원문입니다.

  • safeguard: library headers, Windows DLLs, C/C++/Objective-C packages and dependencies, app bundles (#51)
  • compiler: const &R T is a reference to const; dataflow analysis for heap/arena lifetimes (#52)
  • compiler: expression temporaries die at the end of their full expression (lifetime analysis false positive) (#53)
  • ml: Vulkan (SPIR-V) and WebGPU tensor devices (#54)
  • safeguard: link only the std modules a project uses, with their system libraries; OS-seeded rng; prebuilt std in releases; README (#55)
  • std prebuilt in sections; std always optimized; releases for macOS 11 and glibc 2.25; llvm-nm on Linux CI (#56)
  • std web: URL/query/forms, deflate+gzip, keep-alive server, router, static files, cookies, multipart, SSE, WS client, browser DOM APIs (#57)
  • std: dir/path, CommonMark+GFM markdown, YAML flow, wasm runtime allocator; scx fixes; lexer escape fix (#58)
  • std/audio: real-time audio + MIDI I/O (ALSA, JACK, Core Audio/MIDI, WASAPI/WinMM, WebAudio/Web MIDI, dummy) (#59)
  • std/async: Rust-style futures/executors over goto state machines; goto scope checks in the compiler (#61)
  • README: restore the Async/Await row lost in #57's merge (#62)
  • std/gui: AA vector canvas + TrueType text, multi-window GuiApp, full widget toolkit (#63)
  • Fix main's Windows CI: generic COMDATs after ABI lowering; full-size WSADATA (#64)
  • std/gui: Wayland, web (<canvas>/WebGL/DOM) backends and GPU presenters (GL ES, Metal, D3D11) (#65)
  • HTTPS/TLS: std/tls with OS backends (OpenSSL, SChannel, SecureTransport) and a SafeC TLS 1.3 fallback; https/wss in std/http (#66)
  • README: restore the GUI platforms sentence lost in #66's merge (#67)
  • Fix main's macOS/Windows CI: std_modules check counts linkonce generic instances as linker-merged (#68)
  • safeguard doc (rustdoc-like, built with SafeC's web std) and safeguard publish (git + CI for GitHub/GitLab/Gitea/Forgejo) (#69)
  • selfhost: scc, a SafeC compiler in SafeC emitting WebAssembly — bootstraps, powers the web playground (#70)
  • compiler: promote bool/char/short to int in variadic calls (printf("%d", !x) printed 254) (#71)
  • Close safety gaps: const-ref field writes, ->/call-root escapes, container element references (#72)
  • Fix method calls through by-reference call results; MemoryFlow false positive with StrMap in recursion (#73)
  • compiler: check atomic_cas arguments against the pointee type (#74)
  • Fix main CI on every platform (package.sh, glibc 2.43 headers, macOS/Windows doc and test fixes) (#75)
  • std: no void* and no pointer + length pairs in the public API (slices and typed erasure) (#76)
  • Compiler-enforced Drop and thread safety (Send/Sync, spawn rules, Mutex guards) (#77)
  • compiler/examples/stdlib_complete.sc: port to the slice API (#78)
  • Fix main's macOS/Windows CI: ABI-lowered functions keep their place; mutex test pinned to Linux (#79)
  • std/audio without void*: typed backends, slices, typed FFI; Send+Sync audio/MIDI callback contexts (#80)
  • std: no void* anywhere — typed memory layer, ML autograd/GPU, GUI, TLS, OS bindings; api_lint enforces it (#81)
  • Parser: Typedef** x local declarations; nested prefix operators (**pp, - -x) (#82)
  • Fix bugs found by the docs audit: containers drop their elements, Reactor::drop, WsConn::closed, <math.h> in safeguard, playground time functions (#83)
  • selfhost: fail loudly when a string literal overflows g_tmp (#84)
  • Release 1.0.0-beta-7 (#85)
  • Fix 13 compiler and safeguard bugs: BST compile time, libc headers included twice, libm, __VA_ARGS__, #line, atomic_cas orderings, must_use on prototypes (#86)
  • safec: keep warnings on incremental-cache hits (#87)
  • Release: smoke test accepts a versioned clang; #86 and #87 in the beta-7 changelog (#88)

GitHub 릴리스 페이지 · 변경 내역