As much as C is fantastic to work with, as the general idea of a low/high level language whose compilers are easy to implement, its pain points are annoying.
Integer conversions, literals, unhygienic macros, inconsistent library, overflows, zero-ended strings are all very very fastidious to work with.
I really hope that Zig will grow up because it seems the best promising alternative to C right now. In 20 years or so it might even get a significant market share... Then it will be the turn of POSIX and by 2100 low level system programming will be fixed
Rust has so much syntax for similar semantics that reading rust code is insanely difficult. Even well written Rust can obfuscate intent or details about the implementation when read due to the syntax being terse and broad.
Also, Rust doesn't let you do all of the same things C does without using "unsafe", even if they're perfectly safe. Even with all of that syntax, you're still incapable of telling the rust compiler enough information to allow you to compile certain programs.
For example, in a single threaded Tokio application, shared state across coroutines still requires a 1) heal allocated 2) reference counted 3) mutex protected reference to the state, otherwise Rust won't let you compile even though it would be completely safe to pass around a single stack-allocated reference.
Perhaps I was missing something simple but it was the only way the compiler was happy and seemed to be the only way anyone has gotten it to work.
Unsafe doesn't mean unsafe. It means not provably safe by the compiler. That matters on large code bases, or as code ages and has multiple contributors. Keeping dangerous security bugs out of C is very difficult under those circumstances, but in Rust you can largely trust the compiler and can easily search for all uses of "unsafe" and audit them.
Yes but if you do much low level it is annoying to use a language that constant treats you at best as a dark magic wizard, at worst as a dangerous risk seeker.
All my point was that Rust is not a substitute for C, too heavy and complex and not enough liberating for low level "assembly-wrapping" stuff.
The concept of unsafe language constructs are about 10 years older than C's birthdate, written in different forms, lowercase, uppercase, special module to be imported, whatever, all ignored by C's authors.
As for C being low level "assembly-wrapping" stuff, yeah when all you have is a PDP-11 clone.
They basically answered you. Rust is very complex and big.
A C compiler is relatively easy to implement and it's easy to follow its output if you care about the assembly. For tasks like that, where you want just a lightweight structured programming language on top of assembly, C is very good in principle.
I just want to leave out idiosyncrasies like its automatic type conversions, Rust is way way overkill (and difficult to implement).
Rust is meant to be a replacement for C++, and even then, even if we acknowledge its many merits and C++'s horrible disadvantages, it will always have the handicap of being "different". You can organically grow your abstractions by moving from Assembly, to C, to C++, all in small steps. Writing something in Rust requires somewhat a bigger, discontinuous, step. Not their fault, but that's the state of the ecosystem.
This is a really great list for learning C89/C99! I have to double recommend "Expert C Programming: Deep C Secrets", such a fascinating and fun book (albeit showing some age).
K&R is full of gems, cannot recommend that enough for C. Great not only as reference but initial learning. It’s also so humbling that something 40+ years old (published ‘78) is still used so frequently today.
I also used to religiously target C89 for "maximum compatibility" (`-ansi -pedantic`). But the problem with this approach is that it's 2021, and C89 doesn't have a concurrency model.
FFS, use C11 or newer. Even if you're writing for consoles and weird microcontrollers, the compilers have mostly caught up.
15 comments
[ 4.5 ms ] story [ 48.5 ms ] threadInteger conversions, literals, unhygienic macros, inconsistent library, overflows, zero-ended strings are all very very fastidious to work with.
I really hope that Zig will grow up because it seems the best promising alternative to C right now. In 20 years or so it might even get a significant market share... Then it will be the turn of POSIX and by 2100 low level system programming will be fixed
It’s always good to hear others experience.
Also, Rust doesn't let you do all of the same things C does without using "unsafe", even if they're perfectly safe. Even with all of that syntax, you're still incapable of telling the rust compiler enough information to allow you to compile certain programs.
For example, in a single threaded Tokio application, shared state across coroutines still requires a 1) heal allocated 2) reference counted 3) mutex protected reference to the state, otherwise Rust won't let you compile even though it would be completely safe to pass around a single stack-allocated reference.
Perhaps I was missing something simple but it was the only way the compiler was happy and seemed to be the only way anyone has gotten it to work.
All my point was that Rust is not a substitute for C, too heavy and complex and not enough liberating for low level "assembly-wrapping" stuff.
As for C being low level "assembly-wrapping" stuff, yeah when all you have is a PDP-11 clone.
https://queue.acm.org/detail.cfm?id=3212479
A C compiler is relatively easy to implement and it's easy to follow its output if you care about the assembly. For tasks like that, where you want just a lightweight structured programming language on top of assembly, C is very good in principle.
I just want to leave out idiosyncrasies like its automatic type conversions, Rust is way way overkill (and difficult to implement).
Rust is meant to be a replacement for C++, and even then, even if we acknowledge its many merits and C++'s horrible disadvantages, it will always have the handicap of being "different". You can organically grow your abstractions by moving from Assembly, to C, to C++, all in small steps. Writing something in Rust requires somewhat a bigger, discontinuous, step. Not their fault, but that's the state of the ecosystem.
By the way, GCC will be adding Modula-2 to their frontend mainline.
https://www.phoronix.com/scan.php?page=news_item&px=Modula-2...
FFS, use C11 or newer. Even if you're writing for consoles and weird microcontrollers, the compilers have mostly caught up.