If a programming language evolves to the point that previous programs written in that language no longer compile then it's no longer the same language.
So let's keep C as C and, as you point out, new ideas and concepts that would break things can be implemented in new languages.
C does evolve but it's also taken the pragmatic approach not to break the huge existing code base it has. In many cases these programs have been running for decades, they work.
I don't really buy that you cannot ever introduce breaking changes. That's a recipe for disaster and IMHO short-sighted.
>In many cases these programs have been running for decades, they work.
And in many other cases, they have been full of security holes that take an incredible amount of work to discover.
Something like Rust's editions seems to solve this problem very well, and is indeed what they are intended for.
You can still compile old code, you just won't have full access to new features if you choose to do so. This provides a way to keep legacy systems alive while providing an upgrade path for them at the same time.
>I don't really buy that you cannot ever introduce breaking changes. That's a recipe for disaster and IMHO short-sighted.
It's also empirically true in my experience. See Python2/Python3, Perl/Raku, C++98/C++11/C++20. In the latter case, I'm not even sure there are any significant breaking changes, but the feature sets are so different that I find that I pretty much always have to specify which version of C++ I'm talking about.
For such a tool to be effective it must be possible to statically analyse code to a reasonable degree, and C is certainly not a language that enables easy static analysis.
I actually started using C for my side projects since two years precisely because I want very long term backward compatibility (that is, being able to leave a program for years without maintaining it, then make a small edit in it and build it with minimum pain). C is perfect for that, and I agree with the sentiment that backward compatibility is its most important feature.
Rust actually takes a very strong stance on maintaining backwards compatibility, and Go's stance is arguably even stronger in most cases. You're implying incorrectly that these languages are just breaking things left and right for no reason other than "innovation!", which isn't true.
The overwhelming majority of Rust and Go code from years ago will compile without problems today. Any code from post-1.0 that doesn't compile today was (inadvertently) relying on buggy, incorrect behaviors that have since been fixed... and even then, not all incorrect behaviors get fixed because compatibility is considered so important.
C is fine for certain applications, but no one should choose it for side projects based on some notion of backwards compatibility, in my opinion. If some company is building a business application that needs "backwards compatibility" in the sense that it can run on all sorts of arcane microarchitectures and operating systems, then sure... C is still a really painful* choice, but it might be the right choice then, or if there's an existing C code base, then it probably doesn't make business sense to rewrite it any time soon.
* yes, having no protection from footguns, no real standard library, no built-in concept of asynchronous code, and very little of anything useful is definitely painful. If C is the only valid choice for a project, then it's the only valid choice, and that's what you have to do. The number of projects where you simply can't use something other than C is diminishing by the day.
https://timidger.github.io/posts/i-cant-keep-up-with-idiomat...
there are other similar complaints around the net.
While the C and C++ code I wrote over 2 decades ago is now finally "out of date" as of 5 years ago. It took a while. Not 2-3 years.
Which is absolutely attributed to the language being new, not a design fault.
C is already "settled"
I've been able to compile and run C and C++ code from 20 years ago a truly amazing number of times. It's really surprising at how easy it is to work with well written code even if it's decades old.
Will Rust and Go age that way? Maybe. Too soon to tell.
Not if you have used any third party libraries. Dependency management is a nightmare in these languages.
I spend most of my time working deep in the internals of some things that are 10+ years old running even older versions of some highly (and often badly) modified linux kernels. The well written C/C++ projects definitely stand out.
Of those who do like Common Lisp, many like it because the standard hasn't changed in nearly thirty years (while simultaneously offering features added to the C++ standard just very recently, e.g. a filesystem path abstraction).
But what’s the point he is making. Is there a link to that lecture?
With all of the novel and esoteric programming languages that exist, I wonder why hasn't there been a "I can't believe it's not c/c++" language that breaks these things, but isn't taken seriously enough to diverge completely from the ISO language standards. (for bonus points, with standardized gcc extensions, and something like embedded asm but for compiled languages (like iso standard c))
Or Zig? What other potential C replacement are there?
#define MULTIPLY(a,b) a*b
To ruin your month.
MULTIPLY(2+3,4+5) that expands in
2+34+5 (and not into: (2+3)(4+5)).
To have the latter, you should define:
#define MULTIPLY(a,b) ((a)*(b))
https://stackoverflow.com/questions/14041453/why-are-preproc....
#define DEREFERENCE(b) MULTIPLY(=, b)
int thing DEREFERENCE(ptr);