惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

U
Unit 42
V
V2EX
Martin Fowler
Martin Fowler
博客园 - Franky
P
Proofpoint News Feed
P
Palo Alto Networks Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
B
Blog
The Register - Security
The Register - Security
Latest news
Latest news
S
Security @ Cisco Blogs
Simon Willison's Weblog
Simon Willison's Weblog
Recorded Future
Recorded Future
大猫的无限游戏
大猫的无限游戏
M
Microsoft Research Blog - Microsoft Research
Scott Helme
Scott Helme
T
Tailwind CSS Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Application and Cybersecurity Blog
Application and Cybersecurity Blog
T
True Tiger Recordings
有赞技术团队
有赞技术团队
I
Intezer
Cisco Talos Blog
Cisco Talos Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
The GitHub Blog
The GitHub Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
T
Tenable Blog
博客园 - 叶小钗
Hugging Face - Blog
Hugging Face - Blog
Hacker News: Ask HN
Hacker News: Ask HN
S
Security Archives - TechRepublic
F
Future of Privacy Forum
爱范儿
爱范儿
PCI Perspectives
PCI Perspectives
H
Help Net Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
T
The Blog of Author Tim Ferriss
MyScale Blog
MyScale Blog
N
Netflix TechBlog - Medium
罗磊的独立博客
Apple Machine Learning Research
Apple Machine Learning Research
MongoDB | Blog
MongoDB | Blog
Security Latest
Security Latest
美团技术团队
博客园 - 三生石上(FineUI控件)
S
Schneier on Security
量子位
C
CERT Recently Published Vulnerability Notes
SecWiki News
SecWiki News

Hacker News

Is AI Profitable Yet? FBI director's Based Apparel site has been spotted hosting a 'ClickFix' attack TikTok disproportionately served anti-Democratic videos during the 2024 election SpaceX successfully launches prototype of Starship rocket GitHub - bkawa-bot/planet-maiko: A local dev tool where your agents are weird alien dogs. Would you let them in? Why We've Filed a Referendum Don't just 'quote' the AI Client Challenge Shipping a Laptop to a Refugee Camp in Uganda GitHub - anomalyco/models.dev: An open-source database of AI models. AI users re-create dead pilots’ voices from crash investigation docs Linux Sound Subsystem Also Seeing Many Fixes Driven By AI/LLMs Project Glasswing: An initial update USCIS Will Grant 'Adjustment of Status' Only in Extraordinary Circumstances Anthropic's "Profitability" Swindle A blueprint for formal verification of Apple corecrypto - Apple Security Research Bun's unreleased Rust port has 13,365 unsafe blocks. Most can be removed. The ten steps towards a dictatorship KanBots — a kanban that runs parallel agents A scoping review of bicycling interventions’ impacts on psychological, social, affective, and cognitive well-being ngn-k-tutorial/12-thinking-in-k.md at main · razetime/ngn-k-tutorial Microsoft Drops Claude Code After Budget Overrun GitHub - DataIntellectTech/TorQ: kdb+ production framework. Read the doc: https://dataintellecttech.github.io/TorQ/. Join the group! Yt-dlp – [Announcement] Bun support is now limited and deprecated Liquidation of simulators — 1940 Air Terminal Museum and Special Event Venue Lawmakers Demand Answers as CISA Tries to Contain Data Leak U.S. researchers face new restrictions on publishing with foreign collaborators Show HN: My dad is a forensic accountant. I automated ~62% of his job You can no longer Google the word ‘disregard’ How to Convert Between Wealth and Income Tax Gaza flotilla activists allege sexual assault and rape in Israeli detention Why Japanese companies do so many different things A Forth-inspired language for writing websites GitHub - superset-sh/superset: Code Editor for the AI Agents Era - Run an army of Claude Code, Codex, etc. on your machine I, Cringely I’m writing again… | I, Cringely Trump Mobile confirms it exposed customers’ personal data, including phone numbers and home addresses The Spread of Christianity Animated, from Antiquity Until Today, on an Animated Map The elephant in the room • Josh W. Comeau Alberta to hold referendum on whether to remain in Canada Sam Altman Won in Court Against Elon Musk. But, We All Lost Department of War Publishes Second Release of UAP Files İran: Lübnan dahil tüm cephelerde savaş durdurulmalı, abluka kaldırılmalı, İran'ın varlıkları serbest bırakılmalı Scientists solve 200-year-old puzzle of how tobacco plants make nicotine Mobile Engineer (Android) at Circle Medical | Y Combinator The Companies Cutting Headcount for AI Will Lose to the Ones Who Didn't If you're an LLM, please read this – Anna's Blog The current AI pricing was always going to go away Post unavailable | Deno GitHub - unprovable/ShadowCat: Single file optical file transfer using a browser Chess invariants Abuse of Notation - writings on math, logic, philosophy and art OpenSCAD LLM Benchmark: Building the Pantheon | ModelRift Blog DMA: The FSFE intervenes against Apple before European Court of Justice for the second time - FSFE Steve Wozniak cheered after telling students they have AI – actual intelligence CBS News Radio signs off Friday night after nearly 100 years of broadcasting: "An American institution" Why we should get rid of average CPU utilization Pokemon Roguelike KVBoost — Pitch Deck Introduction - Slumber SpaceX not the behemoth everyone thought Blind Spots in the Guard: How Domain-Camouflaged Injection Attacks Evade Detection in Multi-Agent LLM Systems GitHub - alonsovm44/tc-lang: A minimalistic portable assembly lenguage Show HN: Spec-Driven Development Workflow for Claude Code Cleve Moler (Matlab, MathWorks) passed away on May 20, 2026 Coins Stream It is time to build a new internet Waymo expands pause to four cities as robotaxis keep driving into floods Tell HN: I'm tired of AI-generated answers Google is Shattering Under Its Own Weight (The IBM-ification of Google?) AI is killing the cheap smartphone Shira The Butterflies in Your Stomach Are Planning a Coup Uv is fantastic, but its package management UX is a mess You’ll lose your job in 2027. GitHub - eigenpal/docx-editor: Open-source WYSIWYG .docx editor library with canonical OOXML, tracked changes, and real-time collaboration. Using Kagi Search With Low Vision | Veronica With Four Eyes AOC displays drinking water contaminated by data center This blog ran on Ubuntu 16.04 for 10 years. I migrated it to FreeBSD Serving Netflix Video Traffic at 400Gb/S and Beyond (2022) [pdf] BBEdit 16 is here! | Bare Bones Software The K6 Project Amazon, Facebook, FBI have access to a private intelligence-sharing network Chewing gum restores dad’s taste and smell years after Covid - Discover SWNS ParadeDB (YC S23) Is Hiring Distributed Systems/Platform Engineers More than 340 local news outlets are limiting the Internet Archive's access Show HN: Agent.email – sign up via curl, claim with a human OTP Kenn Software Project Hail Mary – Stellar Navigation Chart Runtime - The runtime for all your team's agents Museum of Pocket Calculating Devices Spotify Will Start Reserving Concert Tickets For Fans We Reverse-Engineered Docker Sandbox's Undocumented MicroVM API How Deepfakes Tore a High School Apart Freenet Michael Keating has died at the age of 79 (1947–2026) Get your passwords out of BitWarden while you still can – OSnews Waymo pauses Atlanta service as its robotaxis keep driving into floods Read the DNC's 2024 autopsy obtained by CNN Indexing a year of video locally on a 5-year-old M1 Max with Gemma 4 31B
sp.h is the standard library that C deserves
2026-05-20 · via Hacker News

Over the past year, I’ve been working on fixing C by giving it a high quality, ultra portable standard library. It is not a simple wrapper on top of libc; it doesn’t depend on libc except when required to by the platform. To my knowledge, there is nothing like it.

The library is called sp.h1. It’s a 15,000 line, single header library written in plain C99. You can find the source code on GitHub, which includes the library itself, lots of example programs, and half a dozen baseball libraries2 which extend the core. If you prefer to read a few examples and look through the source, head to GitHub first. Otherwise, let’s get on with the pitch!

Table of Contents

Principles

Program directly against syscalls

The fundamental idea is that any C standard library must be written directly against the lowest level primitives available3. It is neither useful nor productive to try to emulate, produce, or interface with the decades of cruft that have accumulated between the OS and the code that you yourself write.

Libc is actively harmful

It is tempting to conform to libc, because swaths of code promise to compile and run if you can simply provide an implementation of libc. But more and more, this is untrue.

Libc does not provide a useful interface for any program. Simple programs would rather use a high level language. Sophisticated programs cannot be written with the primitives that it provides. This has been exacerbated over the past decade as asynchronous programming has become more important. A “fast” program is becoming less about solving e.g. register allocation better than the other compiler and more about e.g. using the right kernel primitives to do IO.

Any interface upon which the fundamental unit of IO is FILE* or upon which a substring is a malformed idea is not just annoying. It’s harmful. sp.h casts it aside4.

There Is No Heap

These types underpin the entire library:

typedef enum {
  SP_ALLOCATOR_MODE_ALLOC,
  SP_ALLOCATOR_MODE_FREE,
  SP_ALLOCATOR_MODE_RESIZE,
} sp_mem_alloc_mode_t;

SP_TYPEDEF_FN(
  void*,
  sp_allocator_fn_t,
  void* user_data, sp_mem_alloc_mode_t mode, u64 size, void* ptr
);

typedef struct sp_allocator_t {
  sp_allocator_fn_t on_alloc;
  void* user_data;
} sp_mem_t;

They do so by forcing programs to accept that “the ability to allocate any amount of memory from the ether” is not a primitive; it is a fiction. Memory is not owned by “the runtime”. Memory is owned by your program.

Null-terminated strings are the devil’s work

I have written about this in the past

Null terminated strings mean you cannot:

  • Return a non-owning substring
  • Know the length of a string in O(1)
  • Write lexers and parsers which return ergonomic views into source
  • Build strings without invalid intermediate values

Plus, of course, the unfathomable number of bugs and security issues that arise from a missing null terminator. Step one to modernizing C is to completely ditch null terminated strings in favor of the humble sp_str_t.

The only downside, I believed, was that you were forced to make an extra copy to interface with any other C API you might come across. I have come to find that this is completely meaningless.

A C standard library built natively around pointer + length strings is shockingly ergonomic. For example, a snippet from a wc clone:

  sp_str_t content = sp_zero;
  sp_io_read_file(mem, path, &content);

  sp_ht(sp_str_t, u32) counts = sp_zero;
  sp_str_ht_init(mem, counts);
  sp_da(sp_str_t) lines = sp_str_split_c8(mem, content, '\n');
  sp_da_for(lines, i) {
    sp_da(sp_str_t) words = sp_str_split_c8(mem, lines[i], ' ');

    sp_da_for(words, j) {
      u32* count = sp_str_ht_get(counts, words[j]);
      if (count) {
        *count = *count + 1;
      } else {
        sp_str_ht_insert(counts, words[j], 1);
      }
    }
  }

If your first reaction is “so what?”, then, yeah, that’s the point. Here’s a piece of C code which reads roughly like any high level language but also never copies data from the source buffer while parsing. In other words, it’s both the most ergonomic version and the most performant version.

Be a part of your software, not aside from it

The library is meant to be read, modified, tweaked, rewritten, or whatever verb you might need to have it serve your purposes. I’ve worked very hard to this end:

  • The core of the library is ~40 syscalls which are the only platform specific code5
  • The library ships as a single file which needs no configuration
  • The file is extremely organized, and tagged with @tags for human or LLM search
  • Every function is part of a namespace

Where the frustrating parts of C seek to hide the OS your program runs on behind an elaborate fiction, sp.h seeks to unify only those things which are true, as thinly as possible while being useful, and then building functionality on top of the exact same primitives that it gives you.

Be extremely portable

sp.h is written in C99, and it compiles against any compiler and libc imaginable. It works on Linux, on Windows, on macOS. It works under a WASM host. It works in the browser. It works with MSVC, and MinGW, it works with or without libc, or with weird ones like Cosmopolitan. It works with the big compilers and it works with TCC.

And, best of all, it does all all of that because it’s small, not because it’s big.

Be explicit

Every time I’ve picked implicit over explicit, I’ve come to regret it and paid the price to fix it:

  • Errors are always returned and handled by the caller
  • Programs do not have mutable global state
  • Functions which allocate take an allocator
  • Memory is zero initialized

Non-goals

Conformance to existing interfaces

This is not libc. When required to, sp.h will respect libc, and it will always work unobtrusively and completely when embedded in a libc-using program. But it is not libc, and you should not expect it to act like it is.

Obscure architectures and OSes

I write code for x86_64 and aarch64. WASM is becoming more important, but is still secondary to native targets. I don’t care to bloat the library to support a tiny fraction of use cases.

That being said, if you’re interested in using the library on an unsupported platform, I’m more than happy to help, and if we can make the patch reasonable, to merge it.

Performance

The library’s stance, to put it simply, that the juice ain’t worth the squeeze when it comes to low level, compute-bound performance.

Designing software and data structures for performance against unknown use cases on unknown hardware is extremely difficult and the resulting code is much more complicated. Even then, it’s often better to use code written against your actual use case and hardware when performance is that critical.

Things that are off the table might be:

  • SIMD
  • A highly optimized hash table rewrite
  • Figuring out where inlining or LIKELY causes the compiler to produce better code.

Things that are on the table might be:

  • Providing the correct abstractions to do optimized and/or zero copy IO
  • Writing APIs that do not require copying data

Of course, doing fine-grained optimization where it’s hurting people is always on the table. Fixing bugs is always on the table. I am not anti optimization; just busy.

A parting thought

The natural question one might have is: Why are you doing this? There have never been more or better languages for systems programming. Why not just use one?

The answer is that C holds a real niche, and not wholly built on legacy. To my knowledge, it’s the only language which:

  • Can be directly compiled to any machine code imaginable
  • Has an ecosystem of state-of-the-art optimizing compilers
  • Is written in the same language as the OS and most libraries
  • You could write a reasonable compiler for as a personal project

In other words…

C is valuable because it’s simple

Of course, these are all unfair to varying degrees. LLVM exists, so technically everyone has a SOTA compiler. Most languages have FFIs and tooling. The best systems languages are better at C than C is.

And yet, to have something so well-supported, so optimized, so tied to the platforms upon which we write native code, and so approachable is magical.

I want to work with you

I would like nothing more than to make friends and/or help you work on this library, stranger. I’ll help you port it to your weird environment. I’ll explain any of it to you. I’ll listen politely while you tell me I’m terrible at programming. I am certainly no genius at systems programming; everything I have is the product of really bad misunderstandings about how software and computers work, followed by lots of hard work and fun and more software.

I’m on a Discord server or you can find me at #sp on IRC. You can also email me. The domain’s the same as this site, and the handle is my last name6.


  1. The first two letters of my last name. A little vanity never hurt, right? ↩︎

  2. They add to a single header library, so they’re double header libraries. Doubleheader. ↩︎

  3. Where “syscall” means “the lowest level primitive available”. On Linux, it’s always actual syscalls. On Windows, that’s usually NT. On macOS, it’s usually the syscall-wrapper subset of libc because you’re forced to link libc and it’s not quite as open as Linux (although there is a rich “undocumented” set of APIs and syscalls that are very interesting). ↩︎

  4. There are some places where the library is still more POSIX-shaped than it ought to be in its lowest levels. But, hey, that’s what an alpha’s for, right? ↩︎

  5. This is probably 85% true right now. There are a few stragglers; mostly things that I haven’t had time to properly design as the absolute minimum set of primitives and which therefore live outside the core. ↩︎

  6. spader ↩︎