Why Rust's Explicit Integer Types Are Better Than C's Default Int

Thoughts on Integers (2023)

I explore how popular languages like C, Go, and Swift bias developers toward using generic signed integers, often leading to subtle bugs. In contrast, Rust forces explicit type choices, preventing negative array indexes and clarifying overflow behavior. While C treats signed overflow as undefined behavior for performance, I argue that Rust's approach offers a safer, more intuitive model for modern systems programming.

If you have an integer which you want to treat arithmetically as opposed to in some modular space, Make. It. Signed. If you need more bits, get more bits. Keep it signed.
  1. mike_hock

    > C has a confusing array of machine-dependent types such as ptrdiff_t and size_t

    What's confusing about them? They're basically what int and unsigned int were supposed to be. It's just that they realized they had produced a pile of unextensible shit so they had to add new names.

    While they were at it, they produced the next version of unextensible shit so now int128 can't be added.

  2. krick

    I don't understand what's the conclusion is. I was supposed to "disagree initially and be convinced by the end", but I ended up losing sight of what I was supposed to agree/disagree, and what should I've been convinced of.

    It starts with the premise of "C/C++ have pretty fucked up type systems, and look how much nicer integer type names are in Rust" and also that we should use unsigned integers as the first approximation if we are trying to model ℕ. Was I supposed to disagree with that? It didn't seem like the author was arguing against them, and they seem like pretty trivial, obviously true statements.

    Then it starts to talk about how we cannot properly use unsigned in C/C++, because it's fucked up, and it cannot be fixed properly because the proper handling of integers is too expensive. This all sounds sadly familiar and we are nodding and saying: "Well, such is life." But at least we still have Rust, that doesn't suffer from the same inherent UB curse, right? I mean, I'm not deep enough into the details of current compiler implementation, but I've got the impression that the described problems don't apply to Rust. All good then? (edit: obviously, except for the fact that we still allow wrapping in prod builds, because it's expensive not to. But we all knew this already.)

    Then it follows up with some pretty contrived (IMO) example of how we cannot mindlessly swap int with uint (obviously? I mean, you basically explicitly check for `i == -1` in this example), framing is as " […]

More from this day

2026-07-26