The fact that C was effectively "born old" means you can take a C89 program and compile it as C23 and it should simply work, with extremely minimal changes, if any.
That's a killer feature when you're thinking in decades. Which SQLite is.
The fact that C was effectively "born old" means you can take a C89 program and compile it as C23 and it should simply work, with extremely minimal changes, if any.
That's a killer feature when you're thinking in decades. Which SQLite is.
There has always been undefined behavior in C, but back in the day, compilers were nowhere near as aggressive in taking advantage of it to make your code faster. Most C programmers tended to treat C as portable assembly and not a language with rules that needed to be respected for it to not blow up your code.
I remember this being endlessly groused over by grognard, traditionalist C programmera, and more than a few of them switched to C++ as a result. After all, if the language was going to be a stickler about correctness, they might as well use a language with the features that meant they didn't have to reach into that bag of tricks.
That much is true. If you put the derefence of a pointer and the null check in the wrong order both those statements would have code emitted for them.
Now, it is almost certain that one of those statements would not be emitted.
OTOH, compiling with -O0 still leaves most code to be emitted and fewer dead-code elimination places.
How much wasted work has been created by compiler authors deciding that they know better than the original software authors and silently break working code, but only in release mode? Even worse, -O0 performance is so bad that developers feel obligated to compile with -O2 or more. I will bet dollars to donuts that the vast majority of the material wins of -O2 in most real world use cases is primarily due to better register allocation and good selective inlining, not all the crazy transformations and eliminations that subtly break your code and rely on UB. Yeah, I'm sure they have some microbenchmarks that justify those code breaking "optimizations" but in practice I'll bet those optimizations rarely account for more than 5% of the total runtime of the code. But everyone pays the cost of horrifically slow build times as well as nearly unbounded developer time loss debugging the code the compiler broke.
Of course, part of the problem is developers hating being told they're wrong and complaining about nanny compilers. In this sense, compiler authors have historically been somewhat similar to sycophantic llms. Rather than tell the programmer that their code is wrong, they will do everything they can to coddle the programmer while behind the scenes executing their own agenda and likely getting things wrong all because they were afraid to honestly tell the programmer there was a problem with their instructions.
I don't know where you got this impression but our switches from 2018 to 2021 and now 2024 editions went very smootly. Rust hasn't broken backwards compatibility in any bigger way since 1.0.
int main() {
printf("Sans headers, this is valid C89.");
return 0;
}
Without an explicit declaration, C will consider this function to have the following signature based on the call site: int printf();
By the way, in C () doesn't mean "no parameters" it means "any parameters, which the compiler will infer from the call site and pass to the function."Claiming that editions are an example of rust failing back compat shows a complete ignorance of the ecosystem or what coding in the language is actually like. People in this thread think you can’t mix n match editions or that migrating is some huge unavoidable obstacle. Indeed I have less fear upgrading editions than I do bumping the version of the c or c++ language or even using a newer compiler that exploits accidental UB that had been lurking.