Blog

SafeC 1.0.0-beta-7 released

SafeC 1.0.0-beta-7 was released on 2026-10-27. It is a pre-release: the language and std are still moving quickly.

It is the largest release so far: pull requests #51 through #88, everything merged since 1.0.0-beta-6. What's coming next tracked it as it landed and has the longer write-up of each area; the changelog lists every change down to individual signatures.

Install this exact release:

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

Highlights

  • A web stack (#57): std/http is a keep-alive server with a router and middleware, static files, cookies, multipart forms, server-sent events and WebSocket, plus a URL client that follows redirects and decodes gzip; std/encoding/url and std/encoding/deflate come with it, and std/wasm has full DOM and browser-API interop.
  • HTTPS (#66): std/tls uses the operating system's TLS (OpenSSL, SChannel, Secure Transport) with a SafeC TLS 1.3 fallback, and std/http speaks https:// and wss://.
  • Async (#61): std/async brings Rust's Future / Poll / Waker model as goto state machines, with timers, combinators, channels, a no-heap LocalExecutor, a multi-threaded ThreadPool and async TCP.
  • A GUI toolkit (#63, #65): std/gui has an anti-aliased vector canvas with TrueType text, a widget toolkit and multi-window GuiApp, on X11, Wayland, Win32, Cocoa and the web, with GL ES, Metal and D3D11 presenters.
  • Audio and MIDI (#59): std/audio is one callback API over ALSA, JACK, Core Audio, WASAPI and Web Audio, with MIDI on every platform.
  • safeguard doc and safeguard publish (#69): a rustdoc-style API reference for any package (std's is at /api/), and library publishing with CI, release archives and Pages docs.
  • scc (#70): a SafeC compiler written in SafeC that emits WebAssembly and reproduces itself byte for byte. It runs the Playground in your browser.
  • safeguard packages (#51, #55): C, C++ and Objective-C packages and dependencies, library headers, Windows DLLs and app bundles; a build links only the std modules a project uses, with their system libraries.
  • ML on Vulkan and WebGPU (#54): std/ml tensor devices for SPIR-V (Vulkan) and WebGPU, beside CUDA, ROCm and Metal.
  • Prebuilt std in sections (#56): releases ship std compiled per platform, one archive per section, chosen with install.sh --std=... / install.ps1 -Std ...; the release binaries run on macOS 11 and glibc 2.25 or newer.
  • Versions you can check: safec --version and the new safeguard --version both print 1.0.0-beta-7 (#85).
  • Fixes: variadic calls promote bool / char / short to int; safety-check gaps around const &T field writes, -> escapes and container element references are closed; every container now drops its elements; Typedef** x locals parse; the lifetime analysis treats const &R T as a reference to const and ends expression temporaries at their full expression; and Windows and macOS CI are green (#52, #53, #64, #68, #71–#75, #78, #79, #82–#84).
  • Compiler and safeguard fixes (#86, #87): __VA_ARGS__ expands to every argument; #line works; atomic_cas with "release" / "acq_rel" is valid; including a libc header twice is a no-op; safeguard links libm on Linux; a file with many BST<..., struct> inserts compiles in a fraction of a second instead of tens; warnings are printed again when a file comes from the incremental cache.

Breaking changes

Every breaking change below is reported by the compiler at each affected line — a wrong argument count or type, an ownership error with a note at the declaration, or a missing header. Nothing changes behaviour silently except where the changelog says so.

  • std's API takes slices, not void* or pointer + length pairs (#76, #80, #81). Buffers are []T / []const T, callback contexts are typed ?&T stored as ?&Erased, and no void* is left anywhere in std. Allocators hand out ?&heap unsigned char; audio and MIDI callback contexts must be Send + Sync.
  • Compiler-enforced Drop, Send and Sync (#77). A value of a Drop type must be dropped or moved exactly once on every path; spawn, channels and thread pools accept only data that is safe to share or move.
  • Containers own their elements (#83). clear(), drop() and overwriting a key drop the values; don't free them yourself first.
  • std headers are <std/...> only (#83). safeguard no longer puts std/ itself on the include path, so a bare <math.h> is the C library's and #include <io.h> must become #include <std/io.h>.

Migrating

  1. Buffers: pass slices — f.read(buf[..]), w.write(buf[0..n]), sha256(bytes, digest[..]), str_copy(dst[..], src); safe_memcpy now counts elements. See Types: slices, read-only and optional slices.
  2. Ownership: add defer v.drop(); after creating a value of a Drop type (or release it on every path), and move data into threads with thread_spawn or share it through Mutex<T>. See Ownership & Drop and Thread Safety.
  3. Containers: drop the container alone — remove any m.foreach(free_value) before m.drop(). See Collections: containers own their elements.
  4. Includes: replace #include <io.h> / "prelude.h" with #include <std/io.h> / <std/prelude.h>. See Including std in Standard Library Modules.
  5. Custom allocators and hashers: switch alloc / dealloc to ?&heap unsigned char, and a user Hasher to the slice signatures.

The full before/after table and two runnable examples are in What's coming next: Migrating; the changelog's Breaking changes section lists every changed signature, module by module.

Upgrading

Re-run the installer to upgrade an existing install in place (it installs the newest release, pre-releases included; pass the version to pin this one):

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

Keep your std sections with --std=... / -Std ..., or add one later with --std=+<section>; see Install for every option. Then check what you have:

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

Rebuild your projects from clean (safeguard clean && safeguard build) so nothing compiled against the old std is linked in.

Known issues

This is known in 1.0.0-beta-7:

  • GPU backends are compile-tested only. The CUDA, ROCm, Metal, Vulkan and WebGPU paths in std/ml and std/gui's GPU presenters compile in CI on every platform, but this release has not been run on GPU hardware.

If you hit something else, please open an issue.

Pull requests

  • 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)

The release on GitHub · Changelog