Earlier quoted context omitted.
The performance culture isn't just C. Far from it. Rust was susceptible to Stack Clash because they ripped out their existing stack probing to gain a few percent increase in performance. The article for this thread literally says, "For many use cases ASan is the better choice because it has much less overhead." IME Valgrind does a _much_ better job of detecting memory issues, partly because ASan only detects issues d…
> The performance culture isn't just C. Far from it Sure, but it is where it is more visible, specially micro-optimizing code as it is being written, without validating if it really matters to the application's use case with a profiler. The school of systems programming languages from Algol side, was that correctness was much more relevant than pure performance, Algol dialects for systems programming already had Rust…
Someone else corrected me regarding the stack probes--Rust didn't have probes but actually checked the size of the stack. It's also worth pointing out that often times decisions are premised on maintenance burdens. Performance was one excuse for removing the stack checking in Rust; the other was the maintenance burden of maintaining a feature outside of LLVM.
That goes directly to the heart of the undefinedness issue in C. Doing the "obviously correct" thing wrt to choosing between possible undefined- or implementation-defined behaviors isn't as easy as we think. Good compilers are built on abstractions and code reuse, like any other piece of well-written software. Doing the correct thing in some obvious cases can result in having to make non-obvious tradeoffs elsewhere, possibly having to choose between adding (or maintaining) complexity, or removing a powerful feature, such as deterministic stack overflow prevention.
The history of C (indeed, Unix and the whole "worse is better" school of design) is about favoring less complexity in the tooling while shifting more of the burden onto the user. That's a judgment not about runtime performance, but a very unintuitive judgment about the performance and efficiency of programmer time; that you quickly reach a point of diminishing returns, much sooner than most people believe, putting complexity into, and relying on intrinsic features of, the tooling; that it's often better to make it easier to implement and integrate specialized tools, and easier to reuse existing tools as part of a more focused solution. From that perspective the design of C makes a ton more sense, even if reasonable people can still disagree about the results.
The notion that C--the language design, the ecosystem--is principally about performance is something mostly held by inexperienced programmers. It's a strawman of critics. There were plenty of other languages from the 1970s that were capable of generating faster code than C. Certainly performance was and continues to be of significant concern, but C is hardly unique in that sense. If the debate about how to balance performance with other issues stands-out, I'd argue that's primarily because of C's ubiquitous position and how it and the computing industry (including hardware industry) has co-evolved.
When something seems so "obvious" (security vs performance), yet everybody continues to seemingly repeat the same dumb mistakes, often times what we're missing is that our premises are flawed. Maybe C didn't become ubiquitous because of it's performance, but more so because it was easy to port and easy to build upon. After several years Rust still has a single implementation. Even Go has two production-quality implementations. That's not a criticism of Rust, just an observation that the "security vs performance" axis is hardly the only relevant dimension for judgment and explanation.