Remix.run Logo
jchw a day ago

> It means, stable syntax, lots of mature tooling and compilers, and any problems the language has are well known.

In case of C what it really means is that the compiler codebases are extremely old and sometimes in rather bad shape.

Speaking of stable, C hasn't just stayed still: The C23 standard adds plenty of fun new things, like an annotation for unreachable code. Modern C has threads and synchronization primitives, #embed, complex numbers, and plenty more.

> Of the various languages around, C is the least likely one to have "buggy compilers"

C compilers are still routinely buggy, because the memory model is surprisingly tricky, there are many edge cases in the specification that are subtle and despite being fairly basic are not stressed often enough to come up, and because optimizing C while adhering to its rules about defined behavior is an unending arms race about what is still "technically" compliant with the standard.

Again, this is especially true if we're considering embedded development where the compiler you have might be a random hacked up old build of some vendor compiler rather than at least being recent GCC or Clang. In that case, even if you only consider a small subset of C99, there's still plenty of room for things to go wrong.

By any standard you can come up with, C is just plain-and-simple not a boring reliable solution. As it turns out, something being old and relatively simple isn't enough to make it boring; you can still have a pathological case that is just an absurd clusterfuck.

I will grant you one thing: it is the most boring embedded development solution. But come on. The best modern competition is Rust. Being more boring than Rust is not exactly an impressive accomplishment, especially when you consider how much practical value Rust has to offer.

coldtea 17 hours ago | parent [-]

>In case of C what it really means is that the compiler codebases are extremely old and sometimes in rather bad shape

Statistically nobody writing C code gets to worry about a compiler error.

>Speaking of stable, C hasn't just stayed still: The C23 standard adds plenty of fun new things, like an annotation for unreachable code. Modern C has threads and synchronization primitives, #embed, complex numbers, and plenty more.

Compared to any other modern language, this is so still that C could make a living as a living statue...

>By any standard you can come up with, C is just plain-and-simple not a boring reliable solution.

C is the de facto language that's considered a boring and reliable solution.

The points made are less substance and more pedantic nit picking ("yeah, it's a language with the most mature and relied upon compilers, but the code is old dawg", "yeah, it's one of the most convervative languages to change, and you can compile decades old code just fine, but they added some stuff in C99, C23, etc").

And Rust is still very niche, single compiler, quickly changing affair. Compared to C and C++ adoption (which is a big yardstick of a tech being "boring") it doesn't even register.

high_na_euv 6 hours ago | parent | next [-]

>C is the de facto language that's considered a boring and reliable solution.

Ive spent last year doing C and I disagree, it is not reliable

jchw 2 hours ago | parent | prev [-]

> Statistically nobody writing C code gets to worry about a compiler error.

lol. (Hello, it is me, I am the statistical nobody.)

> C is the de facto language that's considered a boring and reliable solution.

De facto? Yes. Boring? Citation needed.

> The points made are less substance and more pedantic nit picking ("yeah, it's a language with the most mature and relied upon compilers, but the code is old dawg", "yeah, it's one of the most convervative languages to change, and you can compile decades old code just fine, but they added some stuff in C99, C23, etc").

Incredible. You missed some of the most important points while adding new points that neither of us were talking about. Are you alright?

> yeah, it's a language with the most mature and relied upon compilers, but the code is old dawg

I'm not guessing that the code is bad. You go read GCC code.

> it's one of the most convervative [sic] languages to change, and you can compile decades old code just fine

I don't think you even made this point in the first place, but that just means the changes are all backwards compatible. They have to make almost every change backwards compatible because C doesn't have a versioning mechanism.

However, all of the changes were not backwards compatible. You may find that you actually can't compile code that uses variable length arrays. They were made optional and several compilers never implemented them or no longer support them. Granted, it's good they're dead, but it's something that real codebases really used, including for a long time the Linux kernel, only really removed from it to support compiling with LLVM.

In other cases, compiler updates break things that were never standard but were relied on anyways. For example, if you go and compile old code from the 90s and 2000s, you'll often find they either refuse to compile or crash because they were never actually compliant to standard C in the first place. Because the compilers are buggy. They still are, but they used to be, too.

> And Rust is still very niche, single compiler, quickly changing affair. Compared to C and C++ adoption (which is a big yardstick of a tech being "boring") it doesn't even register.

Something being commonplace doesn't make it boring. You missed the most "exciting" part of C, what I consider the magnum opus of why it is never boring and never will be: Undefined behavior.

(And the standard library. Seriously, fuck C's string manipulation functions.)

--

Addendum: Until recently, I actually had a C project where I was using the OpenWatcom 2 fork of OpenWatcom as the primary compiler, due to needing a weird target. While it definitely generally worked, it also gave me a brand new perspective on which to appreciate the stability and reliability of even GCC and MSVC, which I will openly admit rarely run into incorrect compilations.

That said, in my many years of doing C and C++ code, I've run into countless situations where the compiler was, in fact, wrong. Either it refused to compile valid code (MSVC usually, but all of them at times), or it ICE'd during compilation (GCC usually), or it did in fact compile, but did the wrong thing (GCC and LLVM, especially with -O3.) Every time I debugged these down enough to actually report them, someone else was already on top of it, and usually it was even already patched, if not released yet.

I understand that big projects like GCC and LLVM are tricky to maintain, especially since they're dealing with standards as broken and stupid as C. But still, it doesn't change the reality that it's not literally that hard to run into a new compiler bug. The truth is that a lot of us just run into a compiler bug, shrug and make a quick workaround, and then go on our merry way.

There are also some bugs that are kind of bugs and kind of not. For example, the old pointer provenance bug: a comparison of two pointers, which are in fact equal at runtime, can constant fold to being false; it's a valid compilation.

There are many write-ups talking about strange C behaviors, some of which may technically be standards-compliant but are anything but obvious (or boring.)

https://www.ralfj.de/blog/2020/12/14/provenance.html

And sure. It is possible that you never run into any of this fun stuff, of course, but it's extremely easy to experience the degrees to which C is not boring. Just accidentally store a pointer beyond its lifetime (especially a pointer to the stack.) Engage in some undefined behavior of some kind. Suddenly, C becomes... very exciting.