C for Rust Programmers

(bd103.dev)

66 points | by xyproto 2 days ago

13 comments

  • layer8 5 minutes ago
    > Woah, iterating over pointers instead of indexes! […] However, I'm not sure how good an idea that is.

    I’d recommend anyone (including the author) wanting to understand C to read K&R’s “The C Programming Language”, which will illustrate how iterating over pointers is idiomatic in C (though not quite in the way the author’s example does it).

  • uecker 2 hours ago
    Any tutorial for C should explain compiler warnings and other tools that help make code safer. In C, you do not rely on the language specification but on tooling. Especially for Rust programmers, this needs to be explained more explicitly. And of course, you can build abstractions using types in C. So a tutorial should also focus on that, and perhaps not start with a low-level string reversal function.
    • swinglock 1 hour ago
      Absolutely. Turn the warnings into errors too, build and test with sanitizers (ASAN, UBSAN, TSAN) when not measuring performance, and use static analysis beyond compiler warnings (Clang Tidy, Clang Static Analyzer).

      Though the author doesn't look to be trying to write a great tutorial, rather prioritizing sharing what and how they learned something from their perspective.

      • tialaramex 17 minutes ago
        > Turn the warnings into errors too,

        Please stop smashing all the nuance out of compiler diagnostics this way.

        One of the biggest successes of Rust has been its great diagnostics and I can assure you that it would not help to smash my Clippy lint suggesting that what I wrote looks a lot like an implementation of the addition operator† into a fatal error like the one I get for forgetting to initialize a variable.

        Rust even has a (begins empty) diagnostic category [named "expect"] for "This warning should be here" which will flag cases where a notable thing not only might happen here and if it does we can ignore that, but if it's no longer detected that is itself suspicious and should be diagnosed.

        † Yes it does Clippy, and I considered implementing Add but I had a good reason not to, so here is a suppression annotation.

      • cohani 1 hour ago
        Maybe the author was given monetary support from the Rust Foundation, they have given money to people to write blog posts https://rustfoundation.org/media/introducing-our-newest-proj... . They love media instead of technical work.
    • bjackman 2 hours ago
      > This is not a substitute for a proper C tutorial
    • kingforaday 2 hours ago
      I'm with you. Since the post already shows Clang catching the array-decay bug, the author could even just add a “always build with -Wall -Wextra -fsanitize=address,undefined” note and some explanation of course.
    • jminnl 1 hour ago
      Asan!
  • phamilton 1 hour ago
    Re: arrays are pointers.

    One of my favorite things to show just how bare this is in C is to show array access commutativity.

      char c = {1,2,3}
    
      c[1] == *(c + 1)
      
      *(c + 1) == *(1 + c)
      
      c[1] == 1[c]
    
    C is wonderfully simple at times.
    • pwdisswordfishq 18 minutes ago
      I have known about this for quite some time, and the more I think about it, the more useless it seems. Sure, the underlying machine operation is just addition, which is indeed commutative, but at the type system level, the pointer and the offset have distinct roles. It just makes no sense to allow to commute them, just like it makes no sense to allow to commute arguments to, say, strchr, just because the compiler can figure it out by looking at the types. When was the last time you had a practical reason to write "offset + pointer" or "index[array]"?

      In most languages, the indexing operator is not commutative. In Rust, pointer offseting is expressed as a function call or a method, also not commutative. I have never seen a single complaint about either. It's not something people want or care about, it's just a tedious detail.

    • mr_00ff00 53 minutes ago
      All fun and games with arrays being pointers, until you declare an array in a function and return it.
      • jackling 45 minutes ago
        Isn't this easily catchable with static analysis, -Werror -Wall? I've never had a practical problem with this.

        Also arrays aren't pointers in C, they decay into pointers. You can see this since sizeof will work differently in the function that instantiates the array versus one that takes in the pointer as a parameter.

    • Ygg2 48 minutes ago
      Isn't Lisp even more bare bones?

      At end of day minimalism is a neat but not decisive feature. If minimalism was decisive we'd all be writing Brainfuck.

      • brabel 38 minutes ago
        Lisp minimalism is very different. It assumes a runtime with automatic memory management for example, even if the language concepts themselves are minimal, especially in Scheme, it has almost no syntax and just a few core facilities on top of which everything else is built, which are closely related to the Lambda calculus, kind of ignoring completely what real computers actually look like.

        In C the minimalism comes from providing only the minimal set of things that are available in most (maybe all) architectures (the Von Neumann paradigm), like linear memory, a simple function calling convention, close mapping to Assembly operations etc. But C syntax is not very minimalist compared to Lisp , let alone Forth. The fact that C syntax became prevalent in the programming world seems to be mostly an accident to me, it’s not objectively better than those minimalist languages’ or Pascal’s, Prolog, ML families.

      • KerrAvon 23 minutes ago
        I would add on top of brabel's post that C is surprisingly difficult to parse correctly (C++ notoriously so).

        Zoom out a little: C is a lot like Unix: simple probably isn't the right word; `underengineered` comes to mind. Which leads to complexity, as you need to make things work in the real world. And so Unix syscalls being designed in the early 1970's for a PDP-11 don't really map to modern needs. And so every unanalyzed complex C app has memory leaks.

        To be clear, I like C, I like C++, I like Objective-C, I like Swift; I'm comfortable in all of them. But, in 2026, I don't see why for native code everyone shouldn't be programming in Rust / Swift / other modern memory-safe flavor for any new production use. Zig if you want faster compile times, I guess.

    • mathisfun123 37 minutes ago
      > One of my favorite things to show

      Who have you shown this to? What kind of person is impressed by this? Anyone that programs in any other language already knows that syntax is fungible so who cares if C chooses to use addition and brackets this way. So the only people that might be impressed by this are people who don't program. In which case why are you showing them lol.

      For example (assuming you're a C programmer) are you impressed by this python syntax

        [a] * 3 == [a, a, a]
      • junon 29 minutes ago
        Man just let people enjoy small things.
        • mathisfun123 22 minutes ago
          I don't know what you're implying - I asked a genuine question: what is impressive about that syntax.
  • ReDress 3 hours ago
    I'm going to go out on a limb here and make a wild guess.

    That boolean is actually mostly an extension of the integer system whereby we now have an integer type that stores only one bit.

    Whereby the bit stored either results in a 'true' or 'false' value.

    Anyways, I know booleans are useful in systems development when you have strict memory / storage constrains / bandwidth (networks).

    Yeah, that works for me.

    • cogman10 1 hour ago
      The way C handles (prior to C23) booleans is pretty close to how you'd handle booleans in assembly.

      CPUs don't have types, everything is integers or floats. You do your work on registers which have fixed sizes. CPUs have built in instructions for "is this register not zero" which leaks into C. 1 is true in C, but so is 2.

      Also, single bits are rarely used for booleans because it requires more CPU power to extract a single bit. Everything is byte aligned at a minimum.

      When doing something like network code, if you want to store a bunch of booleans you are typically going to either pack them into a byte, or you'll burn the extra bits and send a single byte for the boolean value. Typically this was flags and masks.

      • xhroot 1 hour ago
        > single bits are rarely used for booleans

        SQL Server still has no boolean type and groups bits in the same row into a byte if possible.

    • bjackman 2 hours ago
      'bool' is still at least 1 byte in C. If you want to store one Boolean per bit you have to manually implement a bitmap.
      • viega 1 hour ago
        A bool does automatically cast to an unsized bit slice.

        Meaning, if you have a struct and you want to bit-pack your booleans, you can declare each one as, say, uint8_t some_bool : 1;

        You may then do `x.some_bool = true;` etc.

        It's a small nicety to avoid bitwise operators, anyway.

      • tyromaniac 2 hours ago
        Or pull out the C++ and use std::vector<bool>,... But you should probably never do that
        • randomNumber7 50 minutes ago
          I heard the C++ guys regret defining vector<bool> using 1 bit per value.

          Also for most code it will be premature optimization to worry about that.

          • KerrAvon 34 minutes ago
            From what I can tell in a cursory web search, that regret is more about issues with C++ being unable to abstract that field vs bit divergence properly, not about the concept of having the specialization be bit-based, which is sound.
      • ReDress 1 hour ago
        [dead]
  • rramadass 17 minutes ago
    Read the following if you want to be a C Programmer;

    Fluent C: Principles, Practices and Patterns by Christopher Preschern - https://www.oreilly.com/library/view/fluent-c/9781492097273/

  • kvemkon 1 hour ago
    > the program should check for a null pointer and gracefully exit if one is found: ...

    If malloc() fails, there is no need to exit the program completely with exit(), only return from the current function with an error.

    • randomNumber7 43 minutes ago
      It is impractical to try to recover/continue your program in an out of memory situation for most programs.

      So it is a good advice for beginners.

      • layer8 0 minutes ago
        If the code is in a library (and I’d treat code as if being in a library by default), then the library shouldn’t be deciding that.
  • bjackman 2 hours ago
    It's beautiful to see this perspective! The fact that we are at "whoa, C is fucked up compared to my expectations" instead of "look at Rust's fancy safety stuff" shows that as a field we've started lifting the baseline.

    Nowadays I actually believe I'll likely see a world without memory corruption within my lifetime.

    • cohani 1 hour ago
      Focusing narrowly on memory safety is frequently a distraction that incompetent developers use to excuse their buggy code. "Sure, my Rust code might cause deaths and cause millions of dollars lost; and my code might be unsafe, insecure and incorrect; but at least my code is memory safe and easy to debug when I fuck it up!". And then it often turns out that Rust is not memory safe in practice. https://news.ycombinator.com/item?id=49697392

      The real value of Rust is likely pattern matching and tagged unions. Apart from modules/packages that are not a disaster, like Gabriel Dos Reis the saboteur's disaster with modules in C++.

      • nilslindemann 34 minutes ago
        Were you intentionally rude with your first sentence or just unaware?
    • the__alchemist 1 hour ago
      My take too. (Aside from this being a well-written, clear article, that I think highlighted a fair selection of relevant points; especially the "always use uint8_t instead if int" part).

      I don't see rust a "memory safe" language, or a niche one. I have complaints about it etc, but it's overall a fair baseline of reasonable decisions. When I look at C or other languages rust has learned from, I have more "Yikes, that's rough" takes. So... rust as the language of least "fucked up", to use your phrase? Ownership/safety are one part of the picture, but not what defines it for me.

      • cohani 1 hour ago
        > Rust

        > least "fucked up"

        C has the excuse that it is ancient, but it is tiny and has a lot of different implementations. Rust gccrs is still crawling along, fixing up the huge holes in the Rust "specification" along the way.

        • Ygg2 41 minutes ago
          Rust never had a goal of having well defined spec. It all depends on what ecosystem wants.

          In lieu of that it didn't fuck up.

    • kingforaday 2 hours ago
      It’s definitely great that memory safety is becoming more pervasive. Though I’ll believe “a world without memory corruption” right up until another <insert your relevant hacker hero name> comes along and finds a way through an unsafe block, an FFI boundary, or the hardware itself (Rowhammer says hi).
      • bjackman 1 hour ago
        > Rowhammer says hi

        Yeah I was thinking of prefixing my "memory corruption" with "software-bug induced"! I don't see a credible solution to Rowhammer. ("DDR[n+1] fixes it" - lol)

        > an unsafe block, an FFI boundary

        Honestly these feel solvable to me at this point! I think we'll see:

        - unsafe code shrink as languages get more powerful

        - amount of analysis we can apply to each unsafe line shoot up exponentially as AI gets cheaper

        - amount of FFI we actually need shrink as it gets easier to just click "rewrite it in $lang" on the decision card when your coding agent says "I found a library for that but it's in a different language"

        (Having said all of that, people seem to be adopting Zig for some bizarre reason... So maybe I'm naive to expect unsafe lines to shrink)

        (But also, maybe AI gets so good and so cheap that we can just type "go fidn all the bugs andfi xthenm" into an LLM, between sips of a Piña Colada)

  • pwdisswordfishq 11 minutes ago
    isize and usize seem to be more like intptr_t and uintptr_t. To be fair, for a long time it was not very well-defined to which C type they correspond to; I think that was cleared up only recently.

    It's also a shame the article uses the self-delusional C++ style of pointer declarators.

    Otherwise pretty okay.

  • blourvim 1 hour ago
    It reads really well
  • _dain_ 3 hours ago
    >The very first systems programming language I ever learned was Rust. This is uncommon compared to many other programmers; you're more likely to find someone who learned C or C++ first before coming to Rust.

    It's becoming increasingly common. Rust is my first systems programming language too. I tried to learn C a few years ago but I found it too austere and prickly, which put me off.

    • assimpleaspossi 2 hours ago
      I was going to write that I found this odd. The kid that cuts my grass is going for a degree in CS and told me just yesterday that, in his second year, Java is the language he uses with a little Python. That C was such a struggle and he won't touch it.

      For someone getting a CS degree, that just seems so, so odd. Along with that, he's been studying edge detection in images. In his second year. Not to run off topic but, again, I find that so, so odd.

      • le-mark 57 minutes ago
        When I was in college at a large Midwest university in 2002 intro cs classes were taught in C. Business majors were required to take cs 101 taught in C. We had a project that required implementing linked lists, oh how the business majors suffered! We all did actually but at least the cs majors could use the knowledge!
        • randomNumber7 4 minutes ago
          Stuff like this was often done to enforce a minimum IQ.

          Very reasonable imo as universitys educated people that get positions with responsibilitys.

    • ReDress 3 hours ago
      Probably because C and C++ are mostly used in system and desktop development.

      Rust is taking steps or has been taking steps in this direction too.

      It's not surprising that a lot of experienced systems and desktop development engineers looking to getting their hands on the newest tool already have experience or at least familiarity with C and C++.

  • jmclnx 1 hour ago
    Really just another use Rust instead of c article.
  • BitProgram 2 days ago
    [dead]
  • caaqil 1 hour ago
    > there are plenty of "Rust for C Programmers" articles on the internet, but little to no "C for Rust Programmers" articles out there.

    Why would a Rust programmer learn C? Isn't that basically a regression?

    • cohani 55 minutes ago
      It is easier to write a C compiler from scratch than a Rust compiler from scratch. No usage of LLVM or anything like it.

      That also reflects in that many embedded systems offer C support and do not offer Rust support.

    • orbitaldesk 1 hour ago
      [flagged]