I'll await your Rust ports of Windows, Linux and MacOS then.
This isn't really a fair take. Keep in mind that C/C++ has been the backbone of the most important software in the world since the 1970s. At that time we didn't have virtually unlimited compute and memory at our fingertips the way we do now. It was a huge improvement to have a high level language which still could be optimized nearly as well as assembly.
Its staying power is due to the fact that we really haven't had many good alternatives until maybe the last few years. Things are not going to get ported and rewritten overnight, especially when they largely just work like Linux & PostgreSQL. We'd nuke a huge amount of institutional knowledge and inertia to change those up.
And C/C++ are still key in the embedded space where we still have devices constrained on compute and memory. That's not going to go away anytime soon.
This criticism feel like someone complaining about why anyone still uses horses on the day the Model T was announced. Change takes time.
A pretty big part of the reason we didn't switch earlier is that most people—certainly most non-technical leaders, but also a lot of engineers—don't value correctness or security enough. We didn't have good alternatives until recently because we did not, collectively, invest in developing these alternatives.
One surprising thing is that, in the grand scheme of things, developing an alternative like Rust is not that expensive. It takes something like a small team a few years. Maybe a person-decade of effort to get to a viable point? Maybe two, whatever. The industry as a whole throws away orders of magnitude more engineering-years than that on vanity projects and internal dysfunction every year.
Of course, even once we have an alternative, the switching costs are high. And the barriers are far more social, organizational and political than they are technical. But even so, moving to alternatives incrementally has been viable for decades. And hey, if we include moves to garbage collected languages, we have been moving quite a bit... but we could have been moving more. It was only a matter of will and, upstream of that, cultural change.
So really, the problem isn't that people complain too much, it's that they don't complain enough :)
The real curious thing is serious C/C++ folks seem like one of the least likely groups imaginable, to want to undergo humiliating and embarrassing blunders…
Yet they seemingly don’t mind that it practically guarantees them to make blunders over and over again.
We call them blunders mostly because the solutions are so well known.
In contrast, the last company I worked for did everything in typescript and the amount of problems caused by code that blocked the main event loop was staggering. And at that, our best JavaScript people generally just threw up their arms saying there wasn't a good way to fix it.
Between the two, I prefer a language that lets me fix problems.
"our best java script people" I've used node.js for more than a decade now, I was there for the start of "now everyone is truly full stack"...but yes the majority of developers I've worked with have had no idea about how js etc works on the inside, no knowledge of event loop or what causes the few memory leaks possible in js.
But then again I only know because I love that shit and started out in c/embedded, c# etc. And on my own weak side I fucken suuuuck at frontend related stuff (not the design stuff at all, just...fuck you css).
Pre-Rust "serious C++ folks" used it because it was the best option if you wanted essentially zero performance overhead no heavy runtime and GC spikes. They didn't like the lack of memory safety but it was seen as an unfortunate but necessary trade-off.
These days most of the sensible people have moved from C++ to Rust and so the "serious C++ folks" are an entirely different distribution of people who are much more inclined to think memory safety isn't a big deal and you just have to not make mistakes.
or Swift! I know it isn't super popular outside of Apple ecosystems but I migrated a C 200k LOC personal project to Swift over the last ~4 years and it's gone really well.
Show me a programming language that doesn't result in developers "making blunders over and over again" when developing the kind of very large software C/C++ is used for.
Wrong. It is the market that doesn't value correctness or security enough.
We have the tools (formal verification) to create bug free software (see seL4 and CompCert for example). However customers are not willing to pay for the extra cost needed.
> And the barriers are far more social, organizational and political than they are technical.
At the core it's even more of an economic barrier which isn't even unique to capitalism.
I recall an article talking about why the Romans didn't invent steam engines and things like railroads considering people were aware that steam could be used to do work. The answer was largely that slave labor was so cheap that nobody really cared about finding more efficiency. It didn't solve any problem they had at the time.
The analogy transfers to the tech industry today, economics tend to drive most decisions. While I love technology and think research and innovation is important for its own sake -- particularly because we might not know what we're missing out on unless we explore -- but those controlling the purse strings have other priorities.
Others might point out that the economic cost of the bugs and failure cases in programming languages without memory safety might actually be greater than the cost of developing alternatives or accepting less performance in exchange for correctness. They're probably right! But unless you can measure it and present it on a spreadsheet to the management class, they won't acknowledge or understand it. It's really difficult to measure "incidents you didn't have". In any case it still might be cheaper to work on the next big startup idea, hype it & sell equity -- that strategy has produced trillion-dollar valuations recently. However correctly or incorrectly that may be, the benefit to an elite few is very real.
C is literally "high level assembly" and therefore lacks any guard rails you'd expect in a programming language. It's just unfortunate that so many software developers embraced C for its speed, even when it wasn't strictly needed.
I always remind people that C is a systems programming language and not fit for regular application programming. For that you need an application programming language like Pascal or Java.
I, for one, can't see any speed difference between a program written in Pascal (Total Commander, which I use every day) and one written in C++ (Windows Explorer).
File browsers are probably the worst example you could use here. The actual file manipulations are handled by the OS. The rest of it is just displaying lists of files, so no real speed difference would be noticed in different languages/programs. Most of the time the file browser is just sitting there waiting for user interaction.
The programs that do benefit from speed aren't file browsers.
I certainly also remember the kernel crashing, but this was in the 90s. Later perhaps once or twice on faulty hardware. Shell, I don't think I have seen this ever.
In my case, the crashes were from last year to the start of this one. Some were related to AMDGPU, others to my WiFi card driver, so they're pretty recent.
I don't quite remember the details of the shell crash, I only remember it being on a tool that've never seem crash due to a fault signal. It was somewhat amusing.
C should be considered powerful, more than fast. Part of that power is that it doesn't try to stop you from going so fast it's unsafe. But that's just one way you can choose to use your power.
C is very much a "high level/portable assembly" type language still and there's really no sign that it'll change from that. Even if it has ostensibly has abstract semantics, many operations map to 1 or a few assembly instructions and much C code, even when not strictly conforming (as all but the most trivial examples are), is conforming enough that it's portable amongst most relevant targets
For example, I kinda know that the code
for (size_t i = 0; i < 64; i++) {
// ...
}
...will map to something that roughly that, on x86 will (in most cases) probably do a compare and jump, etc, for the loop body, vectorization and some other optimizations notwithstanding. I know a similar thing will happen on PPC, ARM, etc.
This relationship breaks down a bit with a lot of higher level languages where what you want to occur is higher level. This can be both a blessing and a curse; it can enable easier opportunities for optimization but may also may make automatic things downright pessimizied with very very very large effort and expenditure to get things close to usable.
No, you don't know what that code will do. Depending on the inner block, it'll most likely be vectorized. Like I said, it's significantly higher level than assembly.
I don't really agree here. Setting aside the question of how often a compiler can vectorize a loop, because I do think it's not totally relevant here, as you still don't really have the language builtin stuff that other languages do.
You really do have to write the code that iterates over a list and applies a transformation, you can't just do
[x + y for a.x, a.y in b]
...in C, you have to iterate over the array. And you don't tend to have that much to help you. Most dialects of C don't have exceptions for instance (unless you invent your own). And in general, most of the time, non-trivial loops just... won't autovectorize and it can be a bit finnicky to nudge it in the right direction.
Take, for example, Ghidra. It has a feature to decompile blocks of code into C(++). Other reverse engineering tools follow suit. Even in C, it's very possible to model assembly instructions that don't have a 1-to-1 mapping to a particular language construct as a function call (and this is what these do).
But, there is a reason that, even with all of the architectural differences in the world, whether it be x86, x86-64, PPC, ARM, RISC-V, Xtensa, MIPS, etc, that you can provide a mapping that goes in 1 way (from source to object code) and also the other way (from object code to """source"""). It'd be much more difficult to do that with other languages, especially in an idiomatic fashion.
That change is happening. Microsoft has been rewriting parts of Windows in Rust, Linux is accepting Rust code, and Apple is using Swift for core parts of their OSes.
> I'll await your Rust ports of Windows, Linux and MacOS then.
Unironically this. Like most game developers, I was extremely sceptical of Rust, based on opinions I've read on the internet. Ugliest syntax I've ever seen, and "safety" features are irrelevant and just get in my way. Compile times are glacial. Tons of direct and indirect dependencies needed.
But then I got to use it professionally for a year or so, and I was MINDBLOWN by how much less stuff I have to keep in my working memory at all times. And libs like tokio and actix-web were so well-designed that I actually enjoyed reading the code in my free time. Fighting the borrow checker? I had like five such instances in the first month, understood what it wants and why, and it never bothered me again. Compiles were indeed slow, but I went from "if it complies the first time around, I'm probably missing something" to "if it compiles the first time around, it's most likely correct".
Turns out, I had significantly underestimated what Rust brings to the table, while focusing on stuff that wasn't really that important once you get used to it.
Nowadays I'm back to gamedev. I'm happy about that, because my year in cloud/edge dev felt like we were consistently solving the wrong problems. But I do wish my current team was more open to giving Rust a chance. It solves so many actual problems, and is being dismissed with reasoning like "sorry, I don't have programming socks". And by very smart people! WTF is this timeline?
Granted I doubt how true that is, I always understood the benefits of languages like Haskell and Ada/SPARK, it's just that pragmatically speaking I want beginners in my team to be able to code too.
Computers have gotten more than an order of magnitude faster since safer languages got into the same speed and memory ballpark as C, but we keep wasting that speed. The model T of memory safety was Java 31 years ago. (I'm not sure what lisp is in this analogy.)
It's not a fair take in the sense that replacing the backbone of lead solder plumbing and paint in 1960's wasn't a fair take, and plenty of us are still awaiting the lead-free replacements.
> I'll await your Rust ports of Windows, Linux and MacOS then.
I’d love to have that happen within the next century. I might not be around for it, but I’d say that humanity deserves software that has fewer memory issues.
The thing is, I'm not even against it. The point of the sarcasm was to say that the most massive projects on which everything is built are in C-flavored languages so the claim that it's not fit for large projects is absurd. And to say that replacing those foundations is going to take time. I would love memory safety in those, but it is going to take time to build something as battle-tested.
This isn't really a fair take. Keep in mind that C/C++ has been the backbone of the most important software in the world since the 1970s. At that time we didn't have virtually unlimited compute and memory at our fingertips the way we do now. It was a huge improvement to have a high level language which still could be optimized nearly as well as assembly.
Its staying power is due to the fact that we really haven't had many good alternatives until maybe the last few years. Things are not going to get ported and rewritten overnight, especially when they largely just work like Linux & PostgreSQL. We'd nuke a huge amount of institutional knowledge and inertia to change those up.
And C/C++ are still key in the embedded space where we still have devices constrained on compute and memory. That's not going to go away anytime soon.
This criticism feel like someone complaining about why anyone still uses horses on the day the Model T was announced. Change takes time.