1. 28
  1.  

  2. 8

    Still in the midst of reading this, but just have to say: worst website background ever

    1. 4

      Firefox’s reader mode is a lifesaver here.

      1. 2

        Yes, I had to use that too. I tried to read it the way it was displayed but it was too distracting

      2. 2

        I removed the background and background color via inspector which makes it a lot easier to read.

        1. 1

          I’ve done enough accessibility work on the web to announce: this site’s contrast is great, but its presentation is horrific.

        2. 4

          If you can write a stand-alone program with one function until you get it right - great!

          I saw a cute pattern in the FreeBSD libc source: they included assert.h and declared a main function to run tests in a library source file, guarded by #ifdef TEST. You need only compile with -DTEST and run the resulting binary to test the code. I thought that was real slick for a file with a few smallish functions. I’ve used the pattern a lot since, and I’ve found it’s pretty nice to have the tests in the same file as the source as example usage.

          I totally agree with liberal use of asserts. Since C has such a weak type system, they can kind of act as a substitute. It sucks that basic asserts like “not null” aren’t evaluated statically at compile time, but they do let you assert logical constraints that aren’t easily expressed with types. And they conveniently document the assumptions of all your functions inline with the code.

          But best of all: C asserts trigger a core dump! You can fire up a debugger and examine the entire program state at the time of the crash. No other language gives you that much context for an assertion failure. That alone makes C asserts the best asserts I’ve used out of any language.

          1. 11

            But best of all: C asserts trigger a core dump! You can fire up a debugger and examine the entire program state at the time of the crash. No other language gives you that much context for an assertion failure.

            Hey, Lisp assertion failures simply pause the running image and dump you into the debugger, leaving the entire running state available to inspect and even possibly modify/restart. :-) But I agree it’s otherwise a fairly unusual feature. The IBM Java VM supports core dumps and postmortem debugging, but it isn’t on by default, and I don’t think the standard Hotspot VM supports it.

            edit: Apparently JDK 9 adds this.

            1. 5

              We have the assertion behaviour you’re talking about with Node as well. We run production services with --abort-on-uncaught-exception, and use various assert() style libraries that then throw and trigger a core dump on failure. We can also call process.abort() directly if something is whacky.

              We look at the resulting core files with MDB (and the mdb_v8 module) and can fish out the JS stack, with arguments, as well as effectively every object in the heap. It’s pretty magical. Of course we can also do this with C, as you note, and I am a huge fan of that too!

              1. 2

                Ah, of course joyent / illumos has that capability. If only the linux ecosystem cared about debuggability. :(

                1. 2

                  As one of my former colleagues was fond of saying: I can’t fix others, I can only fix myself. Our software is open source and available if you want it!

              2. 4

                If you do not mind non-standard stuff, you can use __attribute__((nonnull)) (and returns_nonnull) with Clang and GCC, through a macro defined to nothing if not supported. Then you’ll get your compile-time warnings.

                1. 2

                  That’s fantastic, thank you! It’s not as good as a language that standardizes on using option types, but that’ll be damn useful. While we’re talking about attributes, I’m a big fan of warn_unused_result.

                2. 4

                  This is basically how tests work in Rust. It’s pretty great!