Hacker News new | ask | show | jobs
by Joker_vD 1105 days ago
And then in part 2, he spends 5 day figuring out that fgetc returns int, not int8_t, and that apparently this design has consequences. So much for "a simple language that fits in my head". Just as a personal anecdote: I still can't get all the "usual arithmetic conversions" to fit inside my head. But that's just me being stupid and/or forgetful, for sure.

The C language looks like it simple but it's not, it's just a wonderful deception. C has quite an amount of invisible sharp edges and footguns and its standard library has even more footguns and sharp edges of its own design. And with the approach modern C compilers take to UB, the "It's the access and control that it gives me!" is simply not true; it's the compiler that has all the control which the programmer unwittingly gave to it: "unwittingly", because UB is invisible and since "no diagnostic is required", none is provided unless the programmer specifies -Wall -Wextra -Wpedantic; but of course, those options for some reason are unpopular between those former frontend programmers that recently discovered that they love C.

2 comments

I’ve written a chip 8 emulator in both C and Rust and the Rust one is definitely more clear, and with destructured pattern matching you can really cleanly decode the opcodes in Rust: https://github.com/plan-x64/chip8/blob/master/chip8-core/src...

Normally I’d do something like a simple prefix lookup table with function pointers in C for this but chip8 opcodes require parsing the postfix to fully determine the operation (I.e. 8xy[0..e], where x and y are registers) which requires further parsing than a simple lookup table based on prefix.

The C standard library certainly has warts (errno, anyone?) but surely you can't begin to use fgetc() without knowing about EOF… even if you forget that int8_t is not required to exist (people writing int8_t usually mean int_least8_t).