928 comments

[ 53.5 ms ] story [ 1705 ms ] thread
How much support does Microsoft give to the Rust Foundation (financial and otherwise)?

Does Visual Studio (not VS Code) support Rust programming?

Are there plans for an official Rust SDK for Azure? https://github.com/Azure/azure-sdk-for-rust

https://github.com/microsoft/windows-rs

They're a founding member - no idea as to the amount of financial support that Microsoft provides to the Rust Foundation....

Per their membership page, Platinum members provide $300k/year - but of course the real value is paying MSFT employees to work on Rust projects.
Why does Visual Studio need to support Rust when VS Code has amazing Rust support?
It's been ages since I last looked but IIRC Visual Studio is still the go-to and only real option for oldschool win32 programming (i.e. native windows, COM, etc.). I'm sure there are plugins and machinations to make VS Code competent at win32 too but for some companies and shops they're sticking to Visual Studio.
Never underestimate the power of creating UIs with a drag and drop editor. Command line tools for general users ended in the 80’s.

As far as I know, creating and dealing with UIs in Rust is a pain.

I’m waiting for MS Visual Rust.

>> I’m waiting for MS Visual Rust.

My thoughts exactly.

Officially supported tools and SDKs are required in some industries. MS Visual Rust would be awesome!

>> Why does Visual Studio need to support Rust when VS Code has amazing Rust support?

It's about 'skin in the game' and dog-fooding. If Microsoft is serious about Rust, they will use it internally and support it officially.

It's easy to give an opinion on Twitter about how everyone should use Rust and stop using C / C++ for new projects.

Officially supporting Rust in your enterprise software development tools and SDKs shows that you are serious and committed to what you say.

For systems programming, use whatever the Linux kernel uses. For everything else, there is javascript.
>> For systems programming, use whatever the Linux kernel uses.

https://www.zdnet.com/article/linus-torvalds-rust-will-go-in...

>> For everything else, there is javascript.

Scientific / numerical computations? GPU / CUDA programming? Machine learning? Natural language processing?

To be fair, anything done in Python can be said about JS and under V8 will execute faster.

But idk what OP is saying lol

Eh, the main thing that can be done in python is calling all the libraries that have been written for python. Can't do that from JS.
The big stuff is mostly done in C/C++ (because Python is slow) and bound to, so you could end up with basically the same bindings for JS/TS.
The incredibly long time it took to port very popular libraries from Python 2, to Python 3, demonstrates how unrealistic this thought is.
I've tried using both tensorflow and pytorch via their C/C++ apis. It's possible, but just enough of the convenience logic is in python that it's not very practical.

Incidentally if you're going to do it, I recommend pytorch over tensorflow.

A case could be made to consider libraries systems programming, as the "system" is often more than just the kernel. If you have libraries doing the heavy lifting of all that, then the language on top that calls into those libraries for the bulk of the intensive work matters quite a bit less.
> Scientific / numerical computations? GPU / CUDA programming? Machine learning? Natural language processing?

We serve CRUD here, sir.

I don't think it's possible to choose a worse (mainstream) language for general purpose use than Javascript.

If it's not running in the browser it should simply never be JS. That is the only environment where you are stuck with it. Almost anything else is better but you should probably using one of Java/C# or Kotlin/Rust in 2022.

I think this title could be misinterpreted.

There is a difference between Mark Russinovich saying this, as a personal opinion, and Mark Russinovich, Azure CTO, saying this as a company policy/directive.

This tweet does not indicate that it's from him in his official capacity as Azure CTO.

He is the CTO. If he advocates for Rust this much in his personal life, he will advocate it at work. Because he truly believes it will make things better.

Azure will inevitably use Rust more.

I don't want to sound too girle or fanboyish but there is no other way to say it so I'll say it (hopefully he won't read this)- Mark Russinovich transcends titles and if he's said something about technology, it's probably 99.999% true.

Also, RITF, I love Rust but remember zig exists so chill

I also want to say one thing-- sometimes it's not so easy to just decide to write a project and say okay let me write this in Rust. You have to see available ecosystem. I hate python because I'm a systems programmer at heart but damn sometimes all it takes is a pip install, import and 3 lines to get going and understanding things.

Rust ecosystem is hugely lacking. I don't want to spend time writing boilerplate FFI. I've heard zig is better in this regard

Wouldn't pip install and import be equivalent to "cargo new; cargo add; cargo check"?
I think what they're saying is that there isn't always an acceptable third party crate for what they need, but the python ecosystem is more likely to have that front covered.
It’s not until you get well in to your rust project that you realise the only crate for something is missing the feature you need and contemplate if it’s easier to restart in python or submit a PR to the library.
Being true is one hand. Having power of decision is another. For the latter to come, he has to speak in the capacity of a CTO.
The point is that if he was saying it as CTO that would presumably mean Azure is (or will soon) stop starting C/C++ projects.
RITF? Research Institute of Tropical Forestry? Rat Intestinal Trefoil Factor?
RITF: Rust Is The F____
Rust Is The what?

Inquiring minds want to know.

Rust Is The Fuck doesn't parse. Did he mean RITFS, i.e. "Rust Is The Fucking Shit"? He probably didn't mean RITFBAEL, i.e. "Rust Is The Fucking Shit".

What are we hiding here?

Personally, given this is Russinovich - his personal opinion would carry more weight with me than whatever he has to say in his official capacity as Azure CTO.
This guy is the bonafide hero behind sysinternals.

Mark, if you read this, please start with porting Sysmon to Rust. A Microsoft supported doc on how to use Rust when developing using the DDK would be amazing as well.

Sysmon on Linux uses ebpf, would be a selling point if it was also written in Rust.

(comment deleted)
Calling him the Azure CTO is strictly accurate, but HN readers probably know Mark Russinovich better as one of the primary developers of sysinternals[1].

I bring that up to highlight the weight of his opinion: Russinovich is legendary in terms of his systems programming contributions.

[1]: https://en.wikipedia.org/wiki/Sysinternals

absolutely! came here to say just that.

also the excellent book "windows internals", which is kind of like the bsd red book, or the magic garden svr4 book, but for systems derived from the windows nt kernel.

but perhaps his best work is this: https://learn.microsoft.com/en-us/sysinternals/downloads/blu...

a screensaver that produces a realistic blue screen (kernel panic) for the version of the operating system and kernel that are installed, along with a simulated reboot that lands back into bsod as an infinite bootloop. extra bonus points because it also creates fake disk activity (for the era of hdd lights and hdds that made noise) for extra realism during the simulated boot.

I remember trying to install that screensaver yet always having it crash my system, for some reason.

I did wonder how a screensaver can crash the kernel, until I remembered what it's supposed to do.

I was embarrassed for quite a while after that.

Also IMO it's best to avoid his fiction books, Zero Day etc. It's been about a decade since I read it, but it was the first book I've ever read where I felt uncomfortable with the level of detail the author went to when describing the breasts of every female character. The random awkward sex scenes thrown in for no reason was a weird choice.

Most importantly, there's also a complete lack of understanding of the underlying motivations behind both Islamic terror organizations, and cyber crime groups.

I love a ton of things that Mark has built, and I'm glad he's out living his best life. According to the Amazon reviews, a ton of people loved the book, but from my perspective Zero Day is a rare miss.

People like breasts and random sex scenes though, see Game Of Thrones. He was trying to write for the average person I guess....
Actually fascinating. I had no idea. I'm curious if I'll have the same opinion as you after giving this one a read.
> a screensaver that produces a realistic blue screen (kernel panic) for the version of the operating system and kernel that are installed

I used this one at work for some time. Until I came back from my lunch break and got told by my office mate that he helpfully rebooted my PC because it had crashed in my absence.

Re: the screensaver:

> Note: before you can run Bluescreen on Windows 95 or 98, you must copy \winnt\system32\ntoskrnl.exe from a Windows 2000 system to your \Windows directory

There be dragons

Hm? I'm not a particular fan of Microsoft, but his stated opinion here is reflective of a broader trend in software design, one that's coming from both companies and the open source community. I don't see the brainwashing.
His "opinion" is not only reflective, but amplifying, and that's the scary part.

The companies are the ones pushing this "security" stuff, because they want to stop us from doing things like jailbreaking --- and eventually running any software they don't approve of. See https://news.ycombinator.com/item?id=32905587

He used to write very useful utilities which did things that Microsoft didn't officially support or otherwise approve of. That's what made him famous and respected. Now he's using his position to amplify what is effectively a completely opposite viewpoint and betrayed what gave him that respect.

I'm no fan of MS now, and I guess neither Russinovich anymore, but they both used to be far less user-hostile.

Perhaps his years of experience in the space have given him some perspective that leads him to a position other than the one we might have inferred from his previous work.

I can tell you the way I felt about security and open architectures at 25 is very different from the way I feel about them now.

Years of being exposed to the corporate propaganda has had an effect on everyone.

I also feel very different now than I did 2-3 decades ago, because I realised the importance of freedom and how we are slowly losing it.

I don't think Microsoft's interest in Rust boils down to preventing jailbreaking. It'd be far, far cheaper to lobby the US government to ban it.

(Jailbreaking has always been an arms race, and memory corruption exploits may eventually reach their natural end. But that'll probably be because of things like PAC, not Rust. When that happens, I expect jailbreakers to move onto the next low hanging fruit.)

bizarre. not even sure what that linked comment is supposed to do for your argument here. The idea that rust is some plot by "companies" to "prevent jailbreaking" is ..... rough, man.
They're not trying to burn the frog but boil it slowly.

This is just another one of a series of small steps.

You're not crazy. The attacks that Microsoft (and others) are most worried about are attacks from their own customers.
its absurd, and you're slandering a bunch of free software devs who care quite deeply about security and user safety, in service of a total conspiracy theory that quite frankly comes across as trolling. Good luck with that. If by chance you are in fact sincere I have no idea what even to tell you, its just a batshit crazy notion. But odds are strong that you know exactly what you're doing, so, keep at it I guess, whatever winds your clock.
People thought Stallman was a crazy conspiracy theorist back then. Now you'd have to be quite strongly brainwashed to not see how prescient he was.
trolling, trolling, trolling, keep them doggies rolling, rawhide!
(comment deleted)
If you think memory-safe languages are some anti-jailbreaking/rooting conspiracy... well, have you heard of Java?

No. Rust saves countless hours of frustration by eliminating frustratingly-hard-to-debug mistakes that humans commonly make when writing programs. Rust is pedantic, so you don't have to be. Rust saves companies money because Rust software requires noticeably less maintenance. Try it sometime.

Don't worry, I guarantee that man will always be able to break what man can make. You don't need to demonize better software hygiene out of fear that companies will perfectly lock down their devices.

It's not just about jailbreaking or rooting. A lot of other user-hostilities can be defeated because something isn't quite as secure as it could be, and from that perspective, making things "more secure" is active hostility.

"We are not truly free if we do not have the freedom to make mistakes."

I guarantee that man will always be able to break what man can make

Not with the rise of strong crypto.

Java isn't used for OS-level stuff (and I'm glad that it isn't.)

Have you been paying attention? People are glitching chips now to read private keys out of hardware wallets and to bypass secure boot signature checks. And if that's not possible, then you chip the device and bypass its primary boot loader. Even with the rise of strong crypto people still find weaknesses. Your assertion about strong crypto defeating man's ability to break software simply isn't true. You must be from the thin period of history around 2008 for about 10 years where pwning your device had been predominately done in software.

Regardless, you certainly have a warped perception of security. My OS not behaving as it should because someone forgot to remove a pointer from a ring buffer after its data was freed thus allowing malware to compromise my hardware and my personal information--possibly my livelihood--just so you can jailbreak your phone easier is so insanely idiotic it's beyond me. The right solution, if you care about owning your hardware, is to buy a device where you're allowed to replace the secure-boot keys with your own so that you can participate in the advances in security that we've made over time. Or pass a law that requires companies that sell hardware to provide boot loader unlock keys similar to what we did with SIM cards.

Also, java has been used for embedded, real-time, and system level stuff. The Android system notably, ran Java when it was born. And likely so does your bank card.

There are ways to have secure programming languages and secure boot and also own your hardware without yelling at the clouds and wishing them rain 2008 back down on you...

> "We are not truly free if we do not have the freedom to make mistakes."

We don't build bridges that fall down and declare that we've done it out of the need to preserve freedom to experience gravity.

Software engineering is an engineering profession and building reliable software that works as intended is the goal. It's never been the goal to build breakable software... It's been a side effect of decades of engineering compromises to make a product buildable with the tools and resources available at the time. Tools and resources are better now, and it's high time we stopped building things that make it easy for an attacker to steal from your grandmother by compromising her bank's website.

I can assure you that systems will still be hackable and I can assure you that if they aren't, it will be of value to somebody to build a flexible at-your-own-risk system from first principles. The vast, vast majority of humanity is best served by having tools that do what they are designed to do.

I would think that someday I would stop getting shocked by things I see on Hacker News, but the "We need to keep using c++ because buffer overrun attacks are good actually" mentality is a new one on me.

I once thought like that. That was before I realised that corporate interests and those of the user increasingly don't align, and that any strength on their side equates to strength against you.

There needs to be a balance. Any extreme is dystopia. I'm just pushing back because I want to restore that balance.

It may equate to strength against someone; that someone isn't me.

Hackers are a non-protected minority. And they're generally smart enough to think their way out of the world being made harder to hack. For the rest of us, most changes making the world harder to hack are improvements. That's one of the reasons the marketplace keeps rewarding such changes.

the idea that "making things 'more secure' is active hostility", is some grade A trolling, congratulations on that.
"We have to have to keep our systems unsafe so we can have rooting exploits for our devices" is an interesting viewpoint. I can understand why somebody would demand the ability to safely access root, but demanding unsafe code is just wild.
Very very rarely in my life do I feel affectionate towards Windows (and I've been virtually exclusively Linux/other-unix for a long time.) Sometimes it happened when I was writing dumb VBA in some Excel project, which I find fun for some reason. It happens when I play Windows 95/XP era Minesweeper. It also happens when I touch or have to use any part of Sysinternals. I even like reading the docs for Sysinternals, even though the UI is usually so good you hardly need them.
I feel the same way about Sysinternals tools. They give me a warm fuzzy feeling, I think acquiring+maintaining Sysinternals is one of the best things Microsoft's ever done.

The way they expose OS internals in a powerful-but-user-friendly way is delightful and empowering. I still remember the first time I used procmon; it felt like a veil was removed from my eyes, suddenly I could trivially see everything processes were doing!

Sysinternals represents an idealized Windows to me: an OS for power users with a GUI-first culture that differentiates it from Unix. Windows itself might not live up to that dream anymore, but at least we have Sysinternals.

Appeal to authority?
multiple people, myself included, logged in to comment precisely because the idea that MR is mostly aptly described as "Azure CTO" is a bit much. Glad the op commented the way they did, it also obviated this exact argument by simply establishing who exactly he is and not exhaustive foot stomping recitation of all his work.
Appeals to authority are useful and good. They’re shorthands for doing PhD theses on every topic you encounter. They aren’t bulletproof, though.
We do indeed listen to what authorities on subjects have to say, yes. Mark Russinovich is an authority on systems programming, and his thoughts carry weight because of his track record.
yeah, but he's not an authority on everything written in C/C++. He's entitled to his own opinions, but this scope exceeds whatever experience he has doing sysinternals or whatever it was (idk, i'm a unix guy not a windows guy). He definitely can be criticized and disagreed with.

Where does it end? If he says mint chocolate chip is the worst ice cream flavor, am I obliged to agree with him because he made sysinternals?

It should be extremely obvious that you should not jump off of a bridge because he (or anyone else) tells you to.

He’s an expert in the subject at hand, and that fact is more relevant than the fact that he’s the Azure CTO. What more do you want?

(And yes, of course you can disagree with him. That has never been doubted.)

Neither thing.

It means he has a very informed opinion. That doesn't mean we are forced to agree (I do not), but that we must answer with another informed opinion ourselves.

(comment deleted)
How about experience?
This. Experts respect experts not due to political status but experience and demonstrated capability. Status and authority within a technical community are then products of actual results. Nobody is claiming infallibility, but generally when a person voices opinions in a subject within a domain they have previously demonstrated excellence generally people listen.
what's the alternative? invent and validate everything yourself?
Appeal to authority is when you claim something is true just because an "authority" said so.

MR is clearly expressing an opinion and reasons for it and it is up to you to decide whether his experience qualifies him to make such bold claims, whether there are edge cases for exceptions and whether or not you agree or care.

It’s only a falacy if the authority is not an expert in the field they’re speaking about. Example, a religious leader speaking about science matters, or an accountant speaking about engineering matters.

Otherwise, the argument is 100% valid.

Seconding this. I saw the article before its title was changed, and I admit I dismissed it right away (I know, how improper of me).

When I see Mark's name, I stop and read the article.

Lol if you don't know who Mark is and his real world experience particularly developing critical and low level windows tools. I think it's safe to say his opinion on the language and its use with Microsoft/Windows is very relevant.
(comment deleted)
As he appears to have been wholly concerned with details of Microsoft's walled garden, I would not have heard of him. It seems like his opinions today involve only Microsoft's internal management of its hosting products, which nobody outside Microsoft can know much about.
Of all the people to nitpick on that (and it is indeed a ridiculous nitpick), this is not one of them.
Maybe he thinks Azure should standardize on one of Go/Rust, Java/C#, or Haskell/OCaml for managing its hosting service. He is apparently in a position to enforce his opinion on the division. It is hard to know how anybody outside will be able to tell which he has chosen without his announcing it: "Azure has designated Haskell/Ocaml as its preferred language for hosting management utilities."

Microsoft is no stranger to C-suite fads in software development. Back in the 90s each lasted about 2 years. The constant has always been that bugs have never had any detectable effect on company revenues.

What does this have to do with your grandparent comment?
It makes as much sense to talk about a language named "Haskell/Ocaml" as about "C/C++".
Nobody is talking about one language named "C/C++". It's a shorthand for two languages that are closely related at the abstract machine level, and in terms of co-existing compiler frontends.
Then you might as well talk about "C/Rust". Both go to LLVM. But nobody says it, because it would be BS in exactly the same way "C/C++" is.

What matters about a language as a technology, as in the context of this Mark guy's blurb, is how it works in use. There, C and C++ share hardly anything in common: what you do writing good code in one is nothing at all like what you do with the other.

You might get a C program compiled with a C++ compiler, but it would be utterly crappy code, considered as C++.

So, "C/C++" is an inherently dishonest construction. Anybody using it for a context outside of, say, ELF formats or peephole optimization is promoting a lie.

Lying says more about the speaker than about the supposed topic.

LLVM is not a compiler frontend. It’s the middle- and back-ends; Clang is the frontend.

Neither Rust nor C is inextricably linked to LLVM either, as I’m sure you’re aware. And the former doesn’t align with the abstract machine assumed by the latter in important regards, like forward progress.

The rest of this is just a screed. I’m not here to defend his honor, and you shouldn’t waste your time posting about it on random sites on the Internet.

You asked, I answered. I will not waste any more.
What other people are saying about it being a shorthand for similar languages, but also...

C/C++ is a coherent thing to write a single program in. You write some files with a .c extension and compile with gcc, some with c++ and compile with g++, and as long as you're careful in your header files everything works out just fine. People have actually done this, and because C isn't a subset you end up with C files that you can't compile as C++ and you really do have a heterogeneous project.

Haskell/Ocaml isn't comparable.

Haskell and OCaml both have FFI, and means exposing C function symbols, so can call one another.

It is not the same as between C and C++, but it is comparable. But more to the point, it is fully as absurd in the cited context.

The C/C++ people hate it when you call it C/C++.
“It’s time to halt starting any new projects in C or C++”
That's a fairly recent thing that some people do as a kind of virtue signaling.

The "C/C++ Users Journal" was a very popular publication and no one took issue with its name. Nor do people take issue with Dr. Dobbs which has a "C/C++" section with articles from highly influential members of the C/C++ community.

C++ is a complex language, so people invent ways to show how dedicated they are to it, and nowadays that means pretending to get all worked up over the term "C/C++".

I think it's also that idiomatic C++ is evolving further and further away from anything resembling C. So it's turning from C with extra features into a completely separate language that happens to interoperate well with C.
This is true. It's also true that, in terms of abstract machine semantics, C++ is the closest language to C. Similarly, in terms of optimizing compiler implementations, they're the two "core" languages implemented by most frontends. The grouping of "C/C++" makes sense in both of these contexts, at the minimum.
C/C++ is undefined if C is an instance of an integral type.
it's just 1/++
C/C++ is as naïve as ASM/C or Ape/Human.

You come up with examples that are over 30 years old.

Yes my examples are old because the entire point I'm making is that this outrage over "C/C++" is a relatively recent phenomenon. People 10-20 years ago didn't really care or take issue with that term.
I was there and yes we did ;)
I was there and yes we did.

You wish it was recent and something you could pretend about. But anytime you write it, you are telling a lie. Being seen lying tells the reader more about you than you probably intend.

> That's a fairly recent thing that some people do as a kind of virtue signaling.

If by recent you mean well over 20 years ago. When I began learning C circa 2000, I used to hang out on comp.lang.c, and "C/C++" was very much frowned upon. And for good reason--people felt entitled to ask C++ questions in a C newsgroup, which was and remains a poor idea. Even if they were asking questions relevant to both, e.g. regarding pointers, it's still a much better idea to ask in a C++ newsgroup. See https://en.wikipedia.org/wiki/XY_problem

There are people (invariably young) who resist newsgroup etiquette, convinced the etiquette is pointless, or something like virtue signaling. Over the decades they eventually come around to appreciating the wisdom, even if there's never a mea culpa.

The commercial software world, and especially the Windows world, often had a much different culture than what developed online, especially in the FOSS and Unix subcultures. For the latter especially, C++ was relatively uncommon until the 21st century. C++ (with KDE, etc) and then Python had the effect of importing or creating whole new subcultures in these communities without any memory or appreciation of the pre-existing culture.

Not seeing evidence of your claim. A simple search on comp.lang.c for C/C++ turns up plenty of results and no one, not a single person, is calling it out. Infact there's plenty of discussion on an almost daily basis discussing the two languages almost seamlessly. Looks like there's even a alt.comp.lang.learn.c-c++ newsgroup as well.

For reference I also did a search from 1998 to 2002... once again no one cares or is objecting to the term C/C++ and that term is used quite often. From this search I also just learned that Microsoft's own compiler uses the term "C/C++".

Furthermore, if something is relevant to both languages, such as a question involving pointers, why would it be a bad idea to ask about it in a C newsgroup? If anything, it's preferable to ask a question that is pertinent to both languages, especially one involving pointers, in the C newsgroup.

Certainly asking a strictly C++ question in a C newsgroup would be off-topic and rightly so, but asking a question about pointers or other low-level details that are applicable to both languages is perfectly fine in a C newsgroup.

Using 'group:comp.lang.c "C/C++"', here's one of the first hits[1] I get, from May 17, 2000 and starting off,

> I'm just curious, but why is it that people in this group tend to reply with "the language C/C++ does not exist" or "C/C++ is 2, what do you mean?"

https://groups.google.com/g/comp.lang.c/c/bVBTSJ3KRrg/m/uv98... [2]

followed by 14 responses in that thread, most of which explain why that is, none defending the usage. One of the respondents is active on HN, I believe: kazinator (Kaz Kylheku).

I have a local copy of the UTZOO archives, with posts from the 1980s. Out of ~30,000 posts in comp.lang.c and comp.std.c only 284 use the phrase "C/C++". Many of those are discussing specific compilers, e.g., "Zortech C/C++" (this is especially true in other newsgroups). In a quick survey I couldn't find one where people corrected the usage, but if you read those threads most people are careful to provide answers specific to C and don't often repeat "C/C++". Presumably after C and then C++ became standardized people became more vocal about treating them as distinct.

[1] Results weren't sorted by date, and the first page of results spans 30 years.

[2] I wish I could also include a reference ID from the headers, but Google Groups apparently no longer makes them accessible even when logged in. Google Groups Usenet support is horrible, even when searching. It's a real shame. I think Google Groups has even blacklisted comp.lang.c for spam, though almost all the spam in comp.lang.c comes from Google Groups. I've filtered out Google Groups posts from my feed for the past 10 years or so.

Here is a thread starting on April 15, 2000:

https://www.usenetarchives.com/view.php?id=comp.lang.c&mid=P...

started by someone advertising a C/C++ tutorial.

Here, down in the replies, we can find the remark:

In the first place, there is no such language as "C/C++",

Another one:

BTW, what in the world is the C/C++ language

And:

First problem: is comp.lang.c/c++ a legal name for a Usenet forum ?

And:

  Jones
  16/04/2000 17:40:46 UTC

  mike burrell wrote:

  > x*....@m*-****a.com wrote:

  > > I'm beginning a new C/C++ tutorial over at

  >

  > sweet. it's the c/c++ thread all over again.

  Not from me! I'm keeping my mouth shut this time ;)

  Indi 
Look, just believe the people who were there. I was; my name appears in that thread.

Another thread, same year, "NEED C/C++ PROGRAMMER", started by "ITJOBS":

https://www.usenetarchives.com/view.php?id=comp.lang.c&mid=P...

Remarks:

"No such language as C/C++."

"Presumably ITJOBS thinks "Well, I've heard of C and I've heard of C++, but I don't know anything about either. They should be about the same."

"I see this a lot and just want to add that a slash ("/") does not imply a mixture of the two, it just means "and/or", so it would read "C and/or C++".

"All the left-brained, analytical people on comp.lang.c hate "C/C++". The right-brained, "creative" people don't mind it. End of story."

"C/C++ is 1 unless C is 0 in which case the result is undefined (I couldn't resist)"

"Um, no. It's always undefined."

> A simple search on comp.lang.c

I'd love to know where such a thing is possible today.

The distinction actually makes perfect sense during the hiring process.

If a recruiter approaches me with a C/C++ gig then I will immediately assume that either the hiring manager doesn't know what they want or the hiring manager didn't actually write the job specs, none of those scenarios sends a positive signal.

> That's a fairly recent thing that some people do as a kind of virtue signaling.

It was a pretty common correction the comp.lang.c newsgroup in the 1990s.

"Hey you dolt, there is no C/C++; they are different languages."

"Oh yeah? Well look at how when I run cl.exe, it says Microsoft C/C++ compiler!"

"Haha, C/C++ is actually undefined behavior: C++ is modified and independently accessed in the same expression ..."

I certainly don't. Although I also write Rust now, so I suspect someone will accuse me of having split loyalties or something equally ridiculous.

The only context in which I care about "C/C++" is on resumes, where it's a sign that I need to ask a little more about the person's background.

> The only context in which I care about "C/C++" is on resumes, where it's a sign that I need to ask a little more about the person's background.

Is that because you'd expect anyone actually experienced in either to know better than to lump them together so casually?

Not necessarily -- I've interviewed plenty of people where "C/C++" meant "experienced in both, but most work was in C with a small smattering of C++" (or vice versa).

In my experience, it breaks roughly between half that and half recent graduates who took one C course and one C++ course.

For me, I see “C/C++” as a sign they see C++ (which I’m looking for experience in) as interchangeable with C. I want people who grok C++’s ability to build powerful abstractions, not people messing around with it as C with polymorphic classes.
Yes. "C/C++" on a résumé is a red flag.

"Next!"

It's a sign of a liar, and you can round-file it without reading any more.
So far that on a CV has always meant "can write neither C nor C++"
Fair enough. I'll stick to C and C++/Rust.
You see it a lot more often from the Microsoft world since MSVC only supported "C/C++" as a combined language, there was no separate C compiler.
They had a C compiler for kernel drivers.
Really? I don't know much about microsoft's internal architecture after Windows 98. But they maintained a separate compiler for what was basically just kernel modules?
It was a command line only tool distributed with the driver dev kit. It had ABI differences with MSVC that required them to keep it around until relatively recently.
MSVC is a C++ compiler only. It doesn't actually support C.
It does, but I know why you have this interpretation and I think it's fair to have it.

MS only created their compiler to support C all the way up to C89 and it's original standard, with some Microsoftisms in it. MS did not update their compiler to support C99 and subsequent updates until, I think the late 2010s. Since then, they have updated and supported some of the newest C standards.

Well, technically it is one compiler, but it can operate in different modes, depending on the file input. So I don't this distinction is all too relevant.
I personally don't see this level of pedantry from the people I work with. Even if C90/C99/C11/C++98/C++11/C++17/etc are all different, we understand people use "C/C++" to mean "that pervasive family of languages which most systems and libraries are built on".
I envy CTOs with street cred on hn
Well, if online MBA programs are the street, there’s plenty with cred.
I'm waiting for Rust to support both static and dynamical link equally well. static link produces binaries too large for my embedded boards when stdlib is needed. dynamic link looks like a second class citizen to me in Rust. Is there some hope?
The workflow with `cargo` isn't as nice with dynamic linking, but `crate-type = "dylib"` has worked for a while now. Any crate built with that should produce a shared object instead, which you can link in like any other.
Since Rust doesn’t have a stable ABI or separately compiled generics, wouldn’t dylibs necessarily be limited to exporting a C ABI?
My understanding (which might be wrong) is that you can rely on Rust not making incompatible ABI decisions between builds of the same optimization level on the same compiler version. In other words: you don't need to export a C ABI as long as you're able to enforce that every crate is built dynamically with the same compiler and flags.

That is of course still a significant restriction!

ABI shenanigans are what killed the whole "off-the-shelf components" promise of C++ and object orientation.

They really made the same mistake again?

I don't know how you arrived at that. C++ has the exact opposite ABI problems: it has a far-too-stable ABI that leaks thanks to poor abstractions (header files and template expansion in first-party code). Institutional C++ users have far too many implicit ABI dependencies to ever sign off on breakages, so C++ stdlib maintainers are unable to optimize much of the `std` namespace.

This in contrast to Rust, which actually does fulfill the "off-the-shelf" promise for most use cases. It's really refreshing to be able to do `cargo build` on nearly any host and get a single binary.

Edit: Jason Turner covers C++'s ABI woes excellently here: https://www.youtube.com/watch?v=By7b19YIv8Q

C++ has Schrödinger's ABI: some will say that it has a too stable ABI and others will say that its ABI is not stable at all. Which one is it ?

https://stackoverflow.com/questions/67839008/please-explain-...

Can one link two rust static libraries communicating with actual rust symbols (not just C ones), one built with gcc-rs (assuming that this is possible yet), the other built with rustc with its default x86_64-pc-windows-msvc abi ? if not, it's at the exact same state ABI-wise than C++

Well, it's a multiparadigm language, so both :-)

I'm being facetious, but it really is both: it's too unstable in ways that are bad, and also too stable in other ways that are bad.

Edit: since you updated your comment: Rust is not in the same position as C++. C++ has an unstable ABI that it cannot break; Rust has an unstable ABI that it can (and regularly does break). Rust works around this with developer tooling; C++ largely ignores the problem and requires developers to learn the secret rules through blood and tears.

> Rust works around this with developer tooling;

how does that work for companies that may use proprietary rust libraries? the proprietary lib authors won't recompile their shit for you just because you upgraded to the latest rustc

As pointed out, the C ABI is stable. If companies absolutely feel the need to distribute Rust shared libraries and cannot guarantee the compiler being used, then it's a reasonable choice. I suspect that isn't very common, however.

More realistically, the answer is to change the interface: Rust is pretty popular in software architectures where the unit of operation is a networked or IPC'd service; vendors can distribute binaries that communicate at that layer instead.

> vendors can distribute binaries that communicate at that layer instead.

they could do this in C++ also but they overwhelmingly don't, I don't see why they would in any other language for the same target applications

For one, because it's easier in Rust (this goes back to the developer experience and tooling again). But we've now gone from "here's how Rust and C++'s ABI guarantees differ" to "proprietary vendors might not have the easiest time in either language," which is a significant deviation.
The real answer is that Rust doesn’t really seek a solution for this problem. That’s fine, but C++ does and it pays an appropriate price for doing so. That’s just how things are.
I arrived at that through the entire C++/OO/pre-built-components hype of '90s and beyond, the failure of which was blamed on a non-codified ABI.
Rust wants to fix this, but it's an extremely hard problem and other tasks received higher priority.

See "How Swift Achieved Dynamic Linking Where Rust Couldn't" for details: https://faultlore.com/blah/swift-abi/

Thanks for that referral.

On a side note: I like Swift for the most part, but the last time I looked at upcoming language features they seemed like a kitchen-sink approach that's bloating the language and would better have been left to libraries. I've read this sentiment in more than one place, too.

you can use no_std when available.

not sure how dynamic linking would help when your boards don’t have enough (flash ?) space… the linked library still needs to go somewhere? how small of a flash medium are you using?

Maybe multiple entrypoints?

The busybox style of packing everything into subcommands of one big exe is admittedly a hack, but... if it works for Busybox, and it works for Go, and it works for Git, and it works for Docker, then it works for me.

yes no_std for kernel or boot code or MCU boards, that's what rust-embedded is doing and I think it's fine.

many embedded boards typically have 16~64MB Flash running Linux with musl, one rust binary statically linked can easily exceeding 10MB. multi-entry is hard to manage when you have quite a few unrelated tasks, so yes I really need a true shared lib based rust for the mid-range embedded boards, which are, quite a huge number.

I'm not sure what you mean by multi-entry, but it's hard to beat a busybox-style binary for code-size, especially with LTO. If you're building everything into a single filesystem image anyways, this is almost always smaller than dynamic linking.
dylib linking works well enough particularly for embedded cases. As an example Fuchsia did some research on this comparing it to C++. dynamically linking libstd amortized similar savings to dynamically linking libstd++, with trivial binaries going from hundreds of kilobytes to tens of kilobytes with a megabyte sized shared object for std.

As you'll read elsewhere in the thread there isn't an ABI guarantee, as there also isn't so much for C++ either - but particularly for embedded you can solve this in your build process. A competent package manager in a distribution can also solve for this.

This is a tangent, but how do people comply with the MIT (or other) license when statically linking binaries?

You have to include the copyright notice and license, but I almost never see that being done (and, based on the Rust projects I’ve seen, there are often tens, or even hundreds of MIT/BSD/Apache licensed dependencies).

People who use permissive licenses usually don't care about the license-inclusion clause, so most people just don't bother with it until someone comes asking. At the end of the day, fixing that problem is just a matter of including a new text file in the next release. It's nowhere near as big of a deal as when someone complains that you're not complying with the GPL.

By the way, whether you're linking statically or dynamically doesn't affect whether you ought to include the licenses of your dependencies. At least not for BSD, I'm less certain for MIT.

I disagree with both paragraphs.

By choosing a license that requires attribution, developers are communicating a preference. MIT0 and 0BSD exist. If someone does not care about attribution, they would use one of those licenses.

Dynamically linking to a MIT lib is not the same as distributing an MIT lib, so yeah static linking to the lib is completely different, according to the terms of the license.

If you are working professionally as a software developer, or even just appreciate open source contributions, please take licensing terms more seriously.

Kind regards.

That's one of the thing that riles me up. The vast majority of programmers, especially in the open source community, don't take licensing seriously.
They certainly don't care enough to enforce it.

>Dynamically linking to a MIT lib is not the same as distributing an MIT lib

Would you mind citing the clause that makes that distinction?

I’m not a lawyer and this is not legal advice, but…

> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

When statically linking, you’re including a copy of the software, so you’re required to include the notices.

When dynamically linking, you’re not including the software.

Seems pretty straight forward to me.

Ah, I was assuming you're distributing the dynamic library in the package. That's typically what you do on Windows. If you're not doing that then yes, I suppose you don't need to include the license.
agreed, zig only from now on
Zig is production ready? I must have missed the 1.0 release announcement
It's not.

But to be fair it feels more ready than rust did at 1.0

Not to say I'm not excited for Zig, but there are still bugs, miscompilations, and many breaking changes planned. Communicate realistic expectations, lest you become the next language evangelism strike force.
I'm not really over-stating zigs readiness. More pointing out how ready rust wasn't at 1.0.
Looking back, Rust 1.0 was unpolished, but was ready to be 1.0. Rust concentrated on ability to make compatibility commitment, and almost all polishing was postponed. Compatibility commitment stood the test of time.

For example, in Rust 1.0 having a destructor increased object size. This was in no way acceptable as a final design, but they made a plan to fix it in a compatible manner, and actual work was postponed and other things were prioritized. It was fixed one year later in Rust 1.12 without any compatibility problem.

Rust was unusually aggressive about this to ship 1.0 as soon as possible. In general, if it could be fixed compatibly, it was postponed. From what I can observe, Zig doesn't seem to do this, so I can believe Zig now is more polished than Rust 1.0. If so, remember it was a deliberate choice of Rust developers for Rust 1.0 to be unpolished.

There is nothing wrong with using Zig in production before 1.0. You just need to weigh cost and benefit, including cost of dealing with breaking changes.

For example, Dropbox started to use Rust in production before 1.0, see https://blog.convex.dev/a-tale-of-three-codebases/

Zig doesn't satisfy the safety concerns that make even modern C++ undesirable.
Nim is what you want.
are the rumors true, that much of Azure was really bolted-together Ubuntu things.. has that changed, aside from the reality of web-facing service pages growing by the thousands themselves...
No, Azure was never a Linux distribution variant but a NT derived distributed hypervisor OS codenamed RedDog led by Dave Cutler with some heavy VMS experience in the team. It's almost COM+ under the hood.
Imagine how much impact we could have if we used all the effort gong to develop Rust and port everything over to Rust to instead just improve the wrinkles that exist in C++.
If we did that, the Rust folks wouldn't be able to claim credit for the colossal amount of very important code written in C and C++ that gets ported over to Rust. I've never seen a language where feathers in the cap are more important than they are to the Rust community.
Gosh, every Rust post feels like Thanksgiving dinner. Let's settle down.

> ... if we used all the effort gong (sic) to develop Rust and port everything over to Rust to instead just improve the wrinkles that exist in C++.

If you read the tweet, you might notice Mr. Russinovich isn't actually advocating porting everything to Rust. If you'd care to explain how one might iron out the little wrinkles in C++, you have a captive audience.

So he is just complaining without proposing any real solutions then?
> he is just complaining

Um, he is who?

> without proposing any real solutions

If he is Mr. Russinovich, he is saying, "For the sake of security and reliability. the industry should declare those languages as deprecated." Sounds like a proposal to me?

Not without recommending adequate alternatives.
Most of the worst issues with C++ can't actually be fixed without backwards incompatible changes that would break large amounts of existing code. Google spent several years advocating for the approach that you're suggesting, but was unable to persuade other members of the C++ standards committee and recently announced that they're working on a replacement language. The rationale for Carbon goes into great detail on why fixing C++ isn't a viable option.

https://github.com/carbon-language/carbon-lang/blob/trunk/do...

https://github.com/carbon-language/carbon-lang

I don’t feel that his opinion is all-encompassing. If Rust is being used in the name of security and reliability, then C/C++ should remain king of game development, where those two aren’t as important.
C# is the new King of game development.
Only if you're using Unity / Monogame / other custom game engines that use C# as their scripting language.

Unity (IL2CPP) and Monogame (BRUTE) transpile the C# (byte)code to C++ to be able to deploy to consoles and the C# version they support lags several versions behind.

I don't think we can call C# "the new King of gamedev" until it is officially supported by console makers but it seems unrealistic for a couple of years.

Hopefully C# 7's NativeAOT fixes this (Sony & Nintendo will probably need to ship a runtime for C# for this to happen), I don't want to deal with transpiling stuff, I just want C# support out of the box.

As far as I can tell this only improves things on the Unity side.

What I have in mind is just making a game that can run on PS5/Xbox/Switch without using anything other than C# itself (and the platform API). No engines.

I vaguely remember proof-of-concepts/experiments on Nintendo Switch that made it possible to deploy NET Core AOT builds, but it was in some gitter chatroom so sadly I can't find it again.

Anyway, we still have at least a decade before C# or something else with GC takes over. C# is good enough, but something similar to Swift would make me happier.

If you're not using an engine, with a good editor, then you're already firmly among a niche few. The asset pipeline has been the dominating concern in game development for decades now, folks who willingly toss all that aside to write a game from scratch are among the fringe.
> If you're not using an engine, with a good editor, then you're already firmly among a niche few.

Not really. SDL, SFML, Monogame and FNA (and more) do not have editors, but a lot of popular indie titles are shipped with them.

> folks who willingly toss all that aside to write a game from scratch are among the fringe

Check out Dear Imgui. Indie shops such as exok (makers of Celeste) and AAA companies such as Rockstar Games (GTA) use it to create editors for their games.

You don't really need an engine. You probably need a framework if you're going cross-platform. If you're exclusive, you don't even need that.

If we start depending on proprietary engines instead of platform APIs, we're shooting ourselves in the foot in the long-term.

I'm aware of options like SDL, Raylib et al; despite that, indie is still dominated by editor-heavy tools, like Unity. I've been shipping games for nearly 20y; indie and AAA, and good Editors always win.

Even programmer-focused pipelines tend to evolve into designer and artist focused pipelines over time. It's simple: Dear Imgui doesn't solve the problem of rapidly iterating on an asset from Blender/Maya/Houdini; or from rapidly iterating on level design and scripting; or rapidly iterating on sound import and design; or... Over the course of development many indie studios end up reinventing tools that are already cheap or freely available.

Have you tried working with Bevy at all? It's very good: https://bevyengine.org/learn/book/getting-started/ecs/
Hey, I’m not saying Rust wouldn’t be my first choice for game dev. I’m just pointing out the scope of his opinion.
What's the asset pipeline story? Is there an editor, even?

What it looks like is another Raylib, Allegro, Ogre, etc; an engine these days can be expected to have tooling for artists and designers first and foremost.

I've always wondered, why isn't it important here? Are security researchers just not looking?

Especially for networked games.

Companies are definitely juicer targets, but I'm cynical enough to think that it's largely because it's not the game developers money that is at risk of being stolen, the incentives don't line up to encourage good security practices.
Game developers generally persist hand to mouth. Rust isn't popular with us simply because there isn't a Unity or Unreal that offers Rust as a first class offering, and so it's up to the rare few who are interested in building engines from bare to build a new one.
> For the sake of security and reliability.

I just read a few C++ vs Rust comparisons online yesterday and didn't see anything about a significant difference in security or reliability. Mind you the articles weren't very technical.

How is Rust so much more secure and reliable than *modern* C++?

I'd pick Rust over "modern" C++

just because I don't have to deal with 15 compilers, 15 IDEs, 15 build systems, decades of language experiments, kind of compiler-flags driven development

The true real win of Rust. Knowing that you are incredibly likely to be able to compile it without any hoops. Random C/C++ project can still be a roll of the dice.
> you are incredibly likely to be able to compile it without any hoops

Nice.

Does that hold true for cross compiling to arm (Rpi specifically) and Android?

(comment deleted)
Give rust a few decades and it will get there.

Remember when python was simple? And you just had setuptools? Popularity breeds complexity and fragmentation.

Sure. In the meantime that's a few decades of better developer experience.
More like a few decades of extreme churn. Hey dude are you using Crate #43? No, thats dead on github. Try Crate #999. No dude that uses a diff async runtime. Try Crate #888. No dude, that has protest-ware on it and the boss complained. Try Crate #888. No dude, that has incompatible dependencies. Try Crate #456. No dude, that lib causes "fearless concurrency" deadlocks with async. Try crate #999. No dude, that has a gazillion macros and compilation times approach the heat-death of the universe. Try Crate #666...and the story goes on.
Surely C++ doesn't have this problem when using external libraries
Have an upvote for making my day :-).
I ran into those issues when trying to build some old modding software for a game that was written in C++ (Corsix Mod Studio if anyone is wondering).

I was not able to figure out how to get it to build, maybe someday I'll fire up a VM running XP and whatever version of Visual Studio was popular in 2006 and try again.

Don't worry, the GNU people are looking to fix that.
The primary defining quality of Rust (in a security context) is spatial and temporal memory safety: if you're an ordinary user of Rust, you cannot write code that produces memory corruption.

Modern C++ is really nice (I write mostly C++17 and later for work), and does a great job of obsoleting bug-prone patterns from earlier versions of the language. But it's still very easy to introduce memory corruption (of either sort), especially for less experienced C++ engineers. Some kinds of corruption (like double frees) have become even more common as beginner mistakes, in my experience, thanks to the complex mental model required for move construction (compared to Rust, where moves are statically checked).

I would call myself an average C++ programmer. Starting with move semantics in C++11 (very cool!), I found myself frequently making bugs by re-using an "already moved" container (like a vector). I couldn't find any simple way to avoid that mistake. And, from my tooling, it was a hard problem to debug, as are double frees. Do you have any advice to avoid re-using "already moved" containers?
Nothing great, unfortunately -- C++'s decision to leave moved-from values in a "valid but unspecified" state makes a lot of sense from a memory corruption perspective, but has caused plenty of logic bugs in my codebases as well.

The best thing I've used so far is clang-tidy (specifically the "use-after-moved"[1] check). It catches some stuff though, which is better than nothing.

[1]: https://clang.llvm.org/extra/clang-tidy/checks/bugprone/use-...

Good point about clang-tidy. JetBrain's C++ IDE called CLion directly integrates clang-tidy. It is scary how good are some of the suggestions. Absolutely, it makes me a better C++ programmer! It feels like an oldster is tapping me on the shoulder while pair programming: "That one, over there, fix it."
It's well defined safe to use a vector after a move:

    Move constructor. Constructs the container with the contents of other using move semantics. Allocator is obtained by move-construction from the allocator belonging to other. After the move, other is guaranteed to be empty().
https://en.cppreference.com/w/cpp/container/vector/vector

Which can be a useful property at times, but also means tooling won't help you here since it's not an obvious bug.

What he probably means is he imagines the moved-from vector still has elements in it, and indexes into the empty. Another argument for at() outside loops.
Yes, and most algorithms are "surpising" when a container is empty. Most people write, then read, algorithm code imagining a container full of elements. I've been caught by that "bug" so many times, that I now annotate (Java) when containers can be empty. The first few times co-workers see it, they are confused. They they re-read the code, and "oh, I get it. when empty, the code path is very different!" Unlike nullable values, empty collections (usually) don't cause exceptions.
But you can use code that introduces memory corruption. Plenty of crates make use of unsafe blocks.
Unnecessary use of unsafe blocks is stylistically discouraged in Rust, so there's a lot less code that has the potential to harbor a memory safety bug, which makes bugs both less likely to exist and easier to spot when doing a code audit before introducing a dependency on third-party code.
Of course: you can call a C function that's unsound, and that unsoundness can make your surrounding Rust program unsound.

This doesn't change the surrounding point however, which is Rust's philosophy of safeness by construction: if a particular piece of code is safe, then no safe (i.e., invariant-preserving) use of it can be unsafe. That alone makes Rust's security properties strictly better than those of C++, where even the modern safer paradigms can violate underlying invariants.

> How is Rust so much more secure and reliable than *modern* C++?

Rust catches things like use-after-free at compile time. *modern* C++ still lets things slip through e.g.

    #include <iostream>
    #include <string>
    #include <string_view>

    int main() {
      std::string s = "Hellooooooooooooooo ";
      std::string_view sv = s + "World\n";
      std::cout << sv;  // oops, use after free
      return 0;
    }
If by "slip through", you mean "warns you about by default", then yes it lets it slip through.

  clang++ -std=c++17 test.cc
  a.cc:7:29: warning: object backing the pointer will be 
  destroyed at the end of the full-expression [-Wdangling-gsl]
      std::string_view sv = s + "World\n";
                            ^~~~~~~~~~~~~

In any case, I think the philosophical differences between C++ and Rust are well understood, and the different views of the cost/benefits there are also well understood.

In practice, rust will take over when it convinces enough C++ developers that the tradeoff is worthwhile.

That rarely happens by CTO's, or anyone else, telling everyone they are doing it wrong, but instead by helping people see easier ways of doing things, and ways to get work done faster/etc.

Or, you know, waiting for everyone who does it the old way to die.

For trivial examples like this, it's easy to spot.

For modifications on a large codebase months (or years) after the original code happened, it saves significant time and effort to have the compiler catch bugs like this at compile time.

> If by "slip through", you mean "warns you about by default", then yes it lets it slip through.

My bad. I should have been more modern. Try this one:

    #include <iostream>
    #include <string>
    #include <string_view>

    int main() {
      std::string s = "Hellooooooooooooooo ";
      std::string_view sv {s + "World\n"};  // {now even more modern and warning free}
      std::cout << sv;  // oops, use after free
      return 0;
    }
In other words, not a problem.
Except for the use-after-free?
Because nobody does this. An sv is a temporary you pass down the call chain, where it is uniformly perfectly safe.

This is why I say it takes extra work to get things wrong. Every example purporting to show "unavoidable" memory faults is super contrived. You have to turn off compiler warnings to be able to miss it.

My second example (the one you replied to) doesn't require you to turn off compiler warnings.

It might seem contrived, and it is, but it's the essence of a bug that has happened in the real world, distilled to a 10 line example.

And yeah, "use things properly or they will blow up", but enough people don't do that (or mostly do but occasionally slip up) that it becomes a problem.

Look - can we just admit that most C++ apps don't have thousands of use-after-free errors?

Of those use-after-free bugs that exist, they are a large source/percentage of the exploitable security bugs in C++ apps for sure. But again, it's not like apps are usually just littered with use-after-free. Like you may find one in a several million line of code app. They are not that common of a mistake, and FWIW, 100% of them are catchable with things like MSAN.

So people make mistakes. C++ makes certain kinds of those mistakes easy. Rust makes them hard or impossible. I don't think you will find any disagreement about this.

Again - this sort of thing is not going to convince anyone to use rust that doesn't want to already, for lots of reasons, not the least of because they think they are unlikely to make mistakes that matter :)

All this sort of thing does it turn people off from considering it for real, when they should!

(and i say all of this as someone who is funding efforts to replace billions of lines of C++ - i have no love for C++ over rust or vice versa. I just think the current approach here seems very unlikely to result in increased adoption)

> Look - can we just admit that most C++ apps don't have thousands of use-after-free errors?

For sure! It's those one-every-million-lines-of-code ones that are the problem, and that slip through code review and rear their head only in production at odd hours of the day.

> this sort of thing is not going to convince anyone to use rust that doesn't want to already

My post was in reply to someone asking the question what does Rust give you over modern C++, and this was an example showing that modern C++ still has its holes.

I'm not a Rust absolutist, nor do I think everything should be written (or rewritten) in Rust, but the biggest thing going in its favour is that offloads the cognitive load of checking lifetimes and ownership to the compiler, and that turns whole classes of runtime bugs in to compile time bugs.

In a large codebase with many warnings (incl from dependencies which you might not have control over), the difference between a compiler warning and hard error is significant.
It is easily made a hard error using -Werror, or you can even just make this an error if you don't want all warnings to be errors:

  clang++ test.cc -std=c++17 -Werror=dangling-gsl. 
  test.cc:7:29: error: object backing the pointer will be 
  destroyed at the end of the full-expression [-Werror,- 
  Wdangling-gsl]
        std::string_view sv = s + "World\n";
                              ^~~~~~~~~~~~~
It is pretty standard in large codebases in any language to carefully choose sets of warnings and errors.

I do think Rust has lots to offer, but i think the eternal argument here about what the compiler lets you do vs not is not likely to be a winning one with the C++ developers you see who don't want to move over.

`-Wall -Werror -Wextra` is the first thing to add to any project's cpp flags. And then selectively -Wno-whatever the stuff you don't really care about or is too annoying to go fix if it's an existing codebase
I mean I get it. On the other hand you really should know the constructs you are using. std::string_view is essentially a reference to a char array and you are assigning a temporary object (r-value) to it. Standard C++ rules say that you can't expect the lifetime of that object hold past the expression.
Sure I get it too.

If you want to write safe c++ you have to understand memory and lifetimes and what the code is doing. Humans have been shown to be quite bad at doing this - even experienced programmers.

Rust offloads that work to the compiler.

Memory unsafety makes securing large codebases difficult because even minor errors in unimportant parts of a codebase have the potential to compromise an entire binary if an attacker can figure out how to get execution to reach the unsafe code and exploit it. Human code review is fallible and junior engineers exist, so if you want to be confidant that your codebase is free of such vulnerabilities you need to depend on static analysis. Rust makes this a lot easier because a lot of the guarantees you'd want to make using static analysis on your C/C++ codebase are built into the language, and the language helpfully flags for you the sections of code that need careful human scrutiny.
The type system can express thread-safety.

If you try to touch a data structure from a wrong thread, it will stop you at compile time. You don't need to fuzz such problems under a sanitizer. You have a compile-time guarantee for your entire codebase and even your dependencies. If you try to use a thread-unsafe library from a parallelized code, it won't compile, and it will show you exactly which field of which struct needs to be wrapped in atomic or mutex to work (at this point people say "but what about deadlocks!?". They are very easy to track down compared to heisenbug memory corruption.)

This makes parallelization of code relatively easy and way more reliable. Rust markets this as "Fearless concurrency".

Using modern C++ is like walking a tightrope. If you stay within the constraints, you'll do mostly fine. But it's a fine balancing act and there's a steep cliff to fall off if you don't pay enough attention.

Look at it from the perspective of someone brand new to C++. How do they know what is "modern" and the right way to do things, versus "legacy" and the wrong way to do things? As a beginner, there are thousands of resources available to you on the internet -- some new, some decades old -- with code of varying quality that may or may not be "modern". All of it is valid C++ and will compile, but some of it may have footguns that are nonobvious to the new programmer. There's no "modern only" compiler that will reject said footguns, because C++ takes the position that leaving the footguns there is a feature.

This isn't the case with Rust. Maybe it will become more like C++ in the future as the language changes, only time can tell. But for now, code that compiles in Rust is guaranteed to be free from various classes of bugs that still are possible to compile in C++, despite "modern" C++ having fixed various issues.

Another way of saying this is that "just use modern C++" is a variation of "you're holding it wrong" or "just don't write buggy code", which has proven not to be scalable advice that leads to safer software.

(comment deleted)
Someone else downthread: "young developers can pick up Rust quite fast, and that makes it vastly easier than trying to find talented C/C++ developers."

I hope so. I have a hypothesis that the big-O for language success is "How easily can new programmers learn it?" Nothing else matter. JavaScript was slow, but everyone learned it, so it got fast. Python still had bad tooling, but everyone learned it, so it got better. And C got popular in the first place cause it was easier than assembly.

I wanna ask my managers if we could try hiring Rust devs. I don't like hiring people fresh out of college, but I can't manifest more money to hire experienced C++ devs. If the pool of good-enough-Rust devs is growing faster, and maybe already bigger than the good-enough-C++ pool, why am we interviewing people who don't even know what they don't know about C++?

Dunno. Young devs can pick basic Rust constructs fast but when it comes to complicated stuff where performance is critical... There must be raw talent and lot of grind. IMO it's easier to write super complex stuff in C++ than in Rust as there are just too many cognitive things to keep in mind in Rust to even compile. C++ for talented folks makes life easier there. Like JavaScript, yet another language written for bad to average developers to keep them from shooting themselves in the foot.
The complicated stuff is only on compile time. Unlike C++ where the complicated stuff is metastasized between compile time and run time.

Also the truly tricky things in Rust are relatively few and can be escaped with an unsafe.

(comment deleted)
(comment deleted)
Really interesting take, I've had the opposite experience. I've also seen very talented c++ devs screw things up in prod that rust doesn't even allow for. Really recommend taking it more seriously, it's fun once you get a handle on it. Also the tooling is really good now.
C++ has grown several language tools to let you write reliable, safe code.

... But it can't shed the old stuff without breaking backwards compatibility, and that's what bites you. The fact that smart pointers exist now doesn't stop a developer from passing around non -const char* with no size specifier and calling that a "buffer," and because the language is so old and accreted most of its safety features later, the shortest way to express an idea tends to be the likeliest way to be subtly wrong.

This is really just a problem that other languages don't have because they didn't have the same starting point.

It can't shed the old stuff, but it is very, very suspicious -- smelly -- when any of it appears in new code.
It's smelly if you have enough people on the team to know what new code versus old code smells like.

If your developers are coming to the table with some C++ tutorial books written a decade ago, good luck. Invest in a decent linter and opinionated format checker.

The problem is that there is a lot of code and libraries using older patterns. And modern C++ is sufficiently different from the older C++ to constitute effectively a new language while still being unsafe. Moreover, in an attempt to address the efficiency the language has added views and ranges that provides more ways to corrupt memory. So why rewrite libraries in modern C++ when you can port them to Rust or Go and gain memory safety?
However, without a lot of experience, C++ code often turns out to be surprisingly slow.
> Like JavaScript, yet another language written for bad to average developers to keep them from shooting themselves in the foot.

I can't imagine anyone ever describing vanilla JavaScript this way.

Yeah, made me reread the whole message with my sarcasm checker turned up. I can’t recall another widely used language of the era with as many foot-guns or one that went so long without a decent debugging experience.

It really draws into question the claim that “it's easier to write super complex stuff in C++ than in Rust” when so clearly incorrect about JS. Especially when we have _decades_ of evidence from world-stopping vulnerabilities in the C/C++ ecosystem.

With JS I meant it was something to run in a browser, nothing serious (initially). So from the historic perspective it was correct as for the reason why it existed. It was not meant to write multithreaded system services where most bad/average devs struggle (and it's not multithreaded to this day outside webworkers).
> I can’t recall another widely used language of the era with as many foot-guns or one that went so long without a decent debugging experience.

As someone who was writing both in the 2000s: PHP fits this "nicely" haha

I describe it that way. Like everything else in life the path to success is short if you don’t get distracted by unnecessary conventions and a series of bad decisions.
>IMO it's easier to write super complex stuff in C++ than in Rust as there are just too many cognitive things to keep in mind in Rust to even compile.

Surely you can describe this with more than a throwaway sentence, given that more and more people are seeming to experience the opposite.

>Like JavaScript, yet another language written for bad to average developers to keep them from shooting themselves in the foot.

Nobody would describe JS this way - the entire existence of that language is filled with projects attempting to make it better for "bad to average developers" because it is certainly not what you're describing.

Edit: minor formatting of quotes.

> in Rust as there are just too many cognitive things to keep in mind in Rust to even compile.

That hasn’t been my experience. Rust (the language) doesn’t seem to get any more complex as programs get bigger. Lifetimes, while complex in isolation, tend to compose really well.

Most of the pain of learning rust seems to be experienced up front. (Well, other than async but I don’t consider that ready yet).

In comparison, my experience of C++ was that it has way more “spooky action at a distance”. A bug in one part of the code will cause problems in another totally unrelated part of the code. I’ve had memory bugs in C++ which took weeks to track down. Maybe C++ has gotten better - I haven’t touched it in over a decade. I haven’t wanted to. And I can’t see many reasons I’d pick it up now that I know rust.

If you didn't use C++ with the RAII paradigm, and had to write your own new/delete, your previous C++ experience isn't representative of the complexity of dealing with C++ since C++11. The new standards are a massive upgrade, and now a lot of other things are starting to get major quality of life improvements too (eg. template metaprogramming)
This is a really good point. Just like the Great and Powerful oz telling us not to look behind the curtain or you'll see a goofy old man - C++ is quite mighty if you don't look over there at the other stuff.
Rust only released 1.0 in 2015. If you want to complain about pre-C++11 features, I would like to complain about Rust's garbage collector.
Did rust have a GC at some point pre-1.0? Interesting.

Not sure how limiting the discussion of a language to just the features included in the 3rd standard and forward makes sense. Particularly when the old stuff is still present and valid in the later standards.

Just because you want to use some convention curtain off some area of the language doesn't mean it's not there.

https://pcwalton.github.io/_posts/2013-06-02-removing-garbag...

This came 2 years after C++11 was finalized, which introduced RAII memory management, threads, range loops and much more, and is the basis for modern C++.

Of course, there are pros and cons to keeping backwards compatibility with old code. Personally I think it's an amazing technical achievement that the same code written in 1987 still works. Particularly for numerical work there are a lot of libraries that would be a massive pain to rewrite correctly, just getting them off of Fortran was an achievement.

In terms of new and old standards coexisting in the same code, of course it isn't preferable, but it is possible which can enable many use cases, eg. in place upgrades. Forcing rewite-the-world is what caused the Python 2 --> 3 migration to be such a mess.

And if you really don't want old features, there are linter rules and compiler warnings which do a great job for this.

There's a 3rd option between "break the world" and "keep everything the same forever".

Look into rust's editions. Short version: any compilation unit[1] can declare which edition it is written for. The code in that unit must be valid under the rules of the edition, but different units with different editions can be compiled into a larger program.

https://doc.rust-lang.org/edition-guide/editions/index.html

[1] the compilation unit in rust is a crate. That doesn't mean it has to be put into crates.io, just that it has to be cordoned with its own Cargo.toml and any non-public structs/functions/etc will not be accessible from outside the crate.

This is, of course, due to the fact that Rust doesn't have a language specification, just a compiler implementation. If an old version of the compiler has a bug, using an old edition will still have that bug. Contrast this with C++, using an old feature you can still benefit from the latest bugfixes, optimisations, target architectures and instruction sets.

With the new GCC Rust work I believe a new solution will need to be found, and it will end up more similar to the situation with C++.

When you say JavaScript, do you mean java? Rust undoubtedly raises the floor which is great, but designing scalable systems that enable new members to ramp up is a timeless skill independent of language.

As someone who isn’t a rust native but an interested outsider, it can obviously be cumbersome to use on my pet projects compared to something like python, js, c# or C. Dealing with references to generically types traits adds a lot of syntactical burden (re: shit for me to type) and defining types and their implementations leaves something to be desired regarding its grammars.

That being said, my toy programs do not require particularly complex types and the rust compiler is nothing short of a brilliant. The book is a surprisingly easy read, the module system is fine, cargo is decent out of the box, and there is an interesting mix of paradigms in the language itself. In my mind, the power of the compiler is certainly the big feature of rust and that compilers input language is decent enough such that I wouldn’t dislike using it as a daily driver.

> IMO it's easier to write super complex stuff in C++ than in Rust as there are just too many cognitive things to keep in mind in Rust to even compile.

It keeps you from compiling (many of) the bugs you'll happily write and deploy in C++. I don't think there's really much practical difference in "cognitive load" between modern C++ (which is painfully complex in ways that are largely not even useful) and rust. C++ just lets you pretend it's lower and you ship more bugs.

Imo, writing rust is like the best parts of writing C++ with a stern but helpful assistant.

Sure, but don't forget the inherent trade-off - Rust allows you to write safer code at the cost of getting in the way. It simplifies some things and makes other things very complex. It empowers average devs that can suddenly write certain types of system services easily and be reasonably sure they work as intended, but it gets in the way of advanced devs writing core systems.
This sounds an awful lot like how everyone thinks they're an exceptional driver and everyone else is bad. Reality is no one's actually that great at piloting a ton of metal at speeds their brains can't keep up with in an uncontrolled environment.

Anyways, unsafe exists so that if rust is genuinely in your way you can still do what you need to do.

Even C++ requires inline/linked assembler code in certain system cases to squeeze out maximum performance - why would you think Rust is an exception? It has nothing to do with elitism.
If we're talking about raw performance then I'm baffled at what you're talking about to begin with. Rust can link with assembly just as well as c++ and I believe inline asm was stabilized a while ago. Otherwise it's llvm doing the heavy lifting on optimization so clang++ or rust is not much different.

Other than the fact that rust can rely on much much stricter aliasing rules and do a bit better on some optimizations because of it.

Usually when people talk about rust getting in their way they mean the borrow checker, which you can ask to get out of your way and it will still prevent bugs around the unsafe code. Bugs that "advanced programmers" are also prone to, especially around concurrency.

The idea that some programmers are so good they don't make simple but consequential mistakes in code that deals in concurrency and memory management is absolutely elitism.

There is no programmer on the planet who can't benefit from the borrow checker, and if there are any who will benefit less than they are "hindered" by it, there are almost certainly vanishingly few.

It's not easier to write "super complex stuff" in C++ than in Rust, precisely because C++ has much more cruft that the compiler can't check for you.

And so what if Rust is lowering the bar for entry to systems programming? I'd much rather fresh ideas and fresh blood enter the field, than it slowly dying as the only people with arcane C/C++ knowledge slowly retire/die.

There is still quite a lot that you can only ever express in C++. So, no. And plenty of that, you will never be able to express in Rust.
That's a bold claim (since both languages are Turing complete). I presume you meant safe Rust? But that's kinda the point. If something is memory tricky it is supposed to go into unsafe so you can make a safe abstraction around it.

Unless you meant actually all of Rust. In that case, please share what's inexpressible in Rust.

No. I mean that there is a great deal C++ can capture and present in a library that cannot be expressed in Rust. Much of this will never be in Rust because of this or that early choice of direction.

At the most basic level, in Rust you cannot overload operators. You have no opportunity at all to code a move constructor. I could list off others all day long, but you probably would not understand most.

Then there are the things the borrow checker will not let you do, that would be correct, but it can't see that. You might say you can put those in "unsafe", but you can't really field a library where users sometimes must put a call in unsafe.

It is easy to insist you have never needed any of that stuff for your library, but that is really because you have constrained what you even think of trying to do by what you know you can do. We box ourselves in this way automatically, and it takes great effort to break out of such a mental box.

> At the most basic level, in Rust you cannot overload operators.

I've heard this claim multiple places and I don't really understand it. Operators have corresponding traits that you can pretty easily define for your types.

https://doc.rust-lang.org/std/ops/index.html#traits

My reading is that Rust doesn't allow overloading of constructors (don't exist as such) or assignments or whatever is actually needed for copying move constructors.
Well, that's partially true and partially false. Operators are syntax sugar for trait methods. Indeed, some operators can't be overloaded[1]. However, in that case, it's possible to make procedural macros that can handle such cases.

SQL builder programmers, for example, wanted assignment operator overload.

However, I'd argue that it's the wrong kind of overload to enable. The more code can do behind the scenes, the harder it is to reason about it, e.g. :

     c = b;
Is this an assignment? Will it start the DB connection? In Rust, it can be just one thing. By sticking that code in proc macro and translating code, you signal your intent that something funny is happening here and that you should consult docs for more info:

    sql!(a = b)
> It is easy to insist you have never needed any of that stuff for your library,

I didn't say it was easy. I didn't say it was impossible either https://mcyoung.xyz/2021/04/26/move-ctors/.

> Then there are the things the borrow checker will not let you do, that would be correct, but it can't see that.

Sure, but that's the Rice theorem at work (https://en.wikipedia.org/wiki/Rice%27s_theorem). Any non-trivial property of code is undecidable. That's why you have the unsafe escape hatch where you reason about why it's safe.

[1] which isn't that different C++ which prohibits some operator overload, but in C++ the list of operator not overloaded is small

>At the most basic level, in Rust you cannot overload operators

I gave you a working example of operator overloading in Rust a while ago.

Why do you still state that Rust doesn't allow that? Is there a problem with the example?

I know a lot of different languages and have a feature matrix for reviewing them, and I would know if operator overloading didn't work since it's a row in there. It definitely does work in Rust (it's similar to Python's operator overloading).

In complex apps and services, Rust is generally faster than C++ because (especially over the long term, as there's churn in teams) C++ developers copy around stuff way more than necessary.
Are new devs less likely to screw things up in Rust? Probably. Is a modern Rust codebase easier to onboard with than a 40 year old monstrosity of a Microsoft C++ codebase? You bet! Are more people excited about learning Rust? Probably. Is rust much faster to learn than C++? Call me a skeptic.

I've written Rust professionally and would rather write Rust than C++. That said, almost every concept you need to understand C++ is also needed to understand Rust, but then Rust adds additional complex semantics that aren't going to be intuitive to novices and don't trivially map to either other common high-level languages or obvious low-level concepts.

You don’t have to know about exception safety, move semantics, meta-template higgery jiggery, or the 30 years of cruft that C++ has accumulated.

Good riddance.

You don't need to know about about 6 different string types, arcane borrow checker workarounds, RefCell complexity, massive async cruft - acquired by Rust in just 2 years.

C++ will still be used heavily when Rust is buried 6 feet under and HN moves to the next hype language.

> You don't need to know about about 6 different string types

If you're working on a substantial C++ codebase you probably do, actually.

There are no 20 year old Rust codebase to compare with. C++ has gotten easier and cleaner on the last 20 years, whereas Rust has gotten more complicated. If we want to plot future trajectories...
What are you basing this on? I've found Rust has gotten simpler, and the correct things to do has become more ergonomic, if anything.
> You don't need to know about about 6 different string types

Eh, all these "different string" are different because... Well, they have different requirements. Path is not a normal string, it has platform-dependent implications, String/str are UTF8 strings, the byte-esque string have raw bytes, etc. I know I'm being brief, but I hope the differences I'm trying to illustrate are clear, and why it makes sense for these to be different types.

> arcane borrow checker workarounds

You often end up with these in portable/cross-platform C++ or in performance sensitive C++ code. Also, if you've not burdened yourself with OOP-style thinking and adjust your expectations to the fact you're not writing C++ anymore, but a different language, you'll have an easier time learning Rust. All that said, what you call workarounds is probably idiomatic to Rust developers. And even in the most pathological case of workarounds, the resulting Rust code will be much more succinct than any back-breaking efforts to make C++ readable/correct/performant (two of which you get for free in Rust; sans some complicated domains). Like, as examples: just working with std::variant is a nightmare and requires grotesque constructs with visitors patterns (and often lambdas), std::option is a joke that's marginally better than a raw pointer, etc.

> RefCell complexity,

It's no worse than just working with borrowing, and it's not that often you'd use this anyways.

> massive async cruft

Yes, you have a point here, and everyone's aware of this. And people who have ideas in the community about how it can be addressed can easily participate in the discussion and design process if they desire. Whereas C++ is designed by a committee of people who only barely still use the language in the real world (I know there's exceptions, but alas).

Also, if we got tooth for tooth, C++ has an abundance of more complexity than Rust does, and a lot of it isn't even obviously (hence can be dangerous, or just ruin your day/productivity)

> 6 different string types

have fun living your life pretending all strings are of the same type. spoiler alert: it's the wrong kind of fun. it's a bit easier if you're from a native English speaking country, but only until you get blown up by utf-8 (if you're lucky) in production.

(comment deleted)
It's common in other programming languages for string literals to have type string. It's weird and confusing that they do not in both Rust and in C++.
It might be acceptable in higher level languages where some things will simply break in corner cases, at which point the developer will just say 'don't do that' and all is fine. If you're aiming at a true low-level bare-metal-capable syscall-winapi-native-speaker language, this is not an option.
It’s weird and confusing, but also performant. Remember Rust is first and foremost a systems language. You can get a 10x speed boost by using the right string (str vs string) in certain circumstances.
I think you DO have to know about those, or close analogs, in writing Rust. I like both C++ and Rust but I will rise to defend C++.

1. Exception safety becomes "catch_unwind." You might object that nobody cares about that, but major C++ codebases (Google, LLVM, Mozilla) don't care about exceptions; they are built with -fno-exceptions.

2. Move semantics in C++ are annoying, and so is the borrow checker. In Rust you get hit by things like "this code is fine here, but you aren't allowed to refactor it into a function" because there's no interprocedrural visibility into struct fields.

3. Meta-template higgery-jiggery is real and bad in C++, but has a mirror in Rust. With C++ duck-typed generics you write dumb code that does the thing, and then you can refine it with hilariously awful techniques like SFINAE. In Rust you're googling higher-ranked trait bounds before you can even write the thing. What does `for` do again? I think "strongly-typed language, duck-typed generics" is a bit of a sweet spot and C++ has lucked its way into it.

4. "30 years of cruft" means things like "I speak C preprocessor" which is practical. C compat is why C++ is both so awkward and so successful. There's no smooth ramp from C++ to Rust, the way there was from C to C++; that's a choice and maybe the right choice but it has a price.

"Hilariously awful" template metaprogramming is a thing of the past. It has been years since it seemed needed, or since I read any. New, more intuitive features have displaced it.

With concepts in C++20, you get to choose whether templates are duck-typed.

Well, our C++ codebase has a lot of threads that talk a lot, and buffers we'd rather not copy. Plus ad-hoc NIH versions of stuff that exists in Rust's stdlib, like mpsc, or ad-hoc NIH versions of popular crates, like for logging.

I sometimes just wish I could punt to Tokio. Why am I managing threads? Threads are an implementation detail!

I see it as, Rust tells you about the complexity and helps you with it. C++ waits until you trip on it, and then tells you to use Valgrind.

I could be wrong, though. Or I could be 5 years too early.

I think that the C++ version of Tokio is ASIO (either its boost or standalone variant). Neither is in the standard library. 20 Years ago it would have been ACE.
> That said, almost every concept you need to understand C++ is also needed to understand Rust

I agree that many basic C++ concepts are also present in Rust, but C++ is more than just its basic concepts: it's a huge set of features on top of those that interact with each other in complicated ways. Like how constructors aren't functions but something very special. If you just want to be a beginner C++ dev who works alone on their piece of software that doesn't have any dependencies, you can be fine, you just use the subset you are familiar with. But if you want to maintain other people's code, you need to fully understand what it is doing, the C++ features it's using. Rust's whole feature surface is absolutely smaller than that of C++, and the features that exist integrate way better than the C++ features.

Plus, if there is a gap or misconception in your knowledge, in Rust you would get a compiler error, often very well explained. In C++ you would get a segfault, often not a really nice one.

Rust's "feature surface area" reaches or exceeds that of C++ through procedural macros, which surfaces the entire Rust AST to the developer. Major Rust crates like serde use this feature, and when it goes wrong the errors are actively misleading. I've personaly been bitten by this, it's incredibly frustrating to debug. https://serde.rs/derive.html#troubleshooting
I agree that debugging bad macros is annoying, especially proc-macros but that’s not comparable since by their very nature proc macros are no more powerful than hand written code. They cannot create new semantics, at best they can add new syntax sugar for things that already exist in the language.
proc macros are their own walled off thing with well defined input of tokens, and well defined output (also of tokens). You have tooling to inspect their output (cargo expand). Compare this to the average C++ feature which is usually implicit and not visible in syntax and interacts with other C++ features in interesting ways that you have to keep in mind.
Unlike C++, the Rust compiler actually helps you when you encounter those complex concepts, first by refusing to compile in tricky situations, and then by providing helpful suggestions.
Another option is get your existing devs to learn Rust. I think people would be more happy to do that than learn C/C++.
Why not just hire good people and ask them to learn C++. I mean how the heck did anyone actually pass this magic barrier of becoming a "C++ dev" in order to get hired as a C++ dev?
Because, little by little, C++ became "unlearnable".

Long ago C++ made C a little bit more complex. Because there were already lots of C programmers that wasn't a big deal.

But then it didn't stop. Little by little C++ grew into a monstrosity. A lot of people went along. I gave up.

For new programmers to climb in 2-3 years a mountain that seasoned programmers took 15-20 years to climb is asking too much.

Just cus they add a feature to a language doesnt mean u have to use it. Though it does seem very few programmers are smart enough to stick to the most basic features whenever possible.
C++ the "language culture" unfortunately has a lot of gatekeeping as well. The fact that the gatekeeping generally revolves around "replace feature from n-5 years with the newer feature in the latest 0x00x release" is a bit tiresome.

Yes, I'm exaggerating, a bit.

As for the Microsoft whomever-he-is: I agree in theory, I disagree in practice. If there are a lot of C++ devs writing important code, then let them continue to do so in their prime language that they've invested decades of hard work keeping up with the feature treadmill. New devs? Only if you have to.

> "replace feature from n-5 years with the newer feature in the latest 0x00x release"

Let me put a more pro-C++ spin on that sentiment.

C++ is a language that's under long-term development. It might sound weird, but only with C++20 Bjarne Stroustrup felt that his vision for the language was now mostly-realized - and he had worked on it since the 1980s. With other languages, there's a lot of clearing-of-the-desk and starting things anew, while C++ has opted for incremental changes with backwards compatibility to before it existed (i.e. C).

But, looking back, we get the sentiment you describe. Which, rephrased, sounds like this:

"Remember that annoying and ugly hack you had to use so far to get [complex thing] to work? Well, that finally got fixed. Now there's a shiny new language feature / standard library construct which does that more nicely. But your existing code will also work."

A vision that ironically is only fulfilled by Visual C++, and who knows when GCC and clang will manage to reach it, specially in what concerns modules.
Agree 100%. The C++ language and ecosystem shouldn't feel dynamic, given its age and the installed base, and yet it really does. I remember when c++11 came out and all the crazy typedefs I had to type out just disappeared overnight, and I was able to write statements like "using Elem = uint64_t; using Node = MyClass::Node<Elem>;" which were so much more straightforward. Function pointers disappeared too and were replaced by lambdas so I could write my own "each_node" functions and actually have them be really useful.

Then we had concurrency primitives, and now apparently there's a module system in c++20 which should be interesting. C++ clearly has no plans to bow out gracefully or otherwise go quietly into the night, which is fine by me since I still think it's the language which gives me, as a developer, the most freedom and control over the system.

"but only with C++20 Bjarne Stroustrup felt that his vision for the language was now mostly-realized"

So... let me ask you given this statement. Let's say there is an uber smart super productive programmer who states: I can rewrite the entirety of the ecosystem of one language in 1 year....

Would you tell them to rewrite all C/C++ in C++20

or

Rewrite it in Rust?

C++'s only real advantage in the current language marketplace is an installed library base. But how much of that is C++0x2020? Is the barrier to entry of a new programmer in C++ not just 40 years of language revisions, but a massive massive map of libraries where JSON library uses features from v2016, while XML library uses v2005, while some multithreading thing uses v2020...

And then there's the STL, and mixed-in-C standard library, ye gods.

Will Rust turn into that? Well, I think it kind of will to some degree as they try to find dialects that perfectly describe borrower checker semantics. Rust is a syntax soup almost on par with C++, but I guess we'll see.

> Would you tell them to rewrite all C/C++ in C++20 or Rewrite it in Rust?

Neither.

1. I wouldn't trust a person who says something like that. It takes a programming luminary several years to write a good (non-trivial, not-tiny) library the community can get behind, and even that usually involves iterations of use, feedback and partial rewriting/redesign.

2. Why would we want a "rewrite of the entire ecosystem" (whatever that ecosystem may be) all at once? That's a fiasco waiting to happen.

3. An "ecosystem" very often needs to be at least somewhat backwards-compatible, so I wouldn't want it written in something that's just out of the nylons.

Probably best to let that smart programmer write some decent foundational libraries which we can adopt one at a time, with increasing benefit of synergy.

> C++'s only real advantage in the current language marketplace is an installed library base

That seems untrue. C++ has various capabilities in different usage scenarios which other languages do not. But more importantly - programming languages don't all compete: They typically have different combinations of design goals. That's specifically true of C++ vs Rust.

> But how much of that is C++0x2020?

That doesn't matter much. For you, anything that's not written in the latest version of a language may be irrelevant/unusable. Not for the users of backwards (and forwards-) compatible languages like C, C++ and various others.

> Is the barrier to entry of a new programmer in C++ not just 40 years of language revisions

No, 40 years of revisions is not a barrier to entry. Your saying that makes it sound like you are not very familiar with the language.

> mixed-in-C standard library, ye gods.

double x = sqrt(x_squared);

... oh, the humanity! Who would ever write something like this? It's a non-polymorphic function and its symbol doesn't get mangled! Ye gods!

One problem here is that everyone ends up with their own little niches of the language that they like, and nobody's code looks like anyone else's, and suddenly to read a codebase you do need to know huge swathes of the sprawling language.

At lastjob, we did a lot of C++, and I could tell whose code I was reading without checking blame because I knew who liked what idioms and features.

> One problem here is that everyone ends up with their own little niches of the language that they like

Amusingly, this was always the criticism I've seen leveled at Lisps over the years. It's just as true in C++ for sure.

This is so true. Two examples.

1. I got a couple of downvotes a few days ago because I commented that I don't like the &s of Elixir (kind of shortcuts for 'fn x ->') and I prefer to write the full form as it's easier to read for everyone no matter how proficient in the language (zero to expert.) I also don't like and almost don't use the & shortcuts in Ruby (positional arguments.)

2. I got a customer recently with the lead developer fond of each_with_object. I never saw that in 17 years of Ruby and I had to check the reference. It's probably faster than the naive implementation (more time inside the C implementation doing real work vs inside the C parser?) but the naive one is immediately readable by anyone.

Wouldn't that mean there should be no competing crates, because people should write the same code for the same task?
> Just cus they add a feature to a language doesnt mean u have to use it

While I absolutely agree with this in general, in practice with C++ if you're trying to use it safely you do in fact need to use those new features. But the old features are all still around too. It's a very, very large language in terms of mental space required these days.

In what world is C++ harder to learn than Rust?
This world - the one you exist in right now. I say that as someone that wrote C++ for 10 years before moving to Rust.

Rust was by far easier.

That said - that’s an extremely biased statement and I recognize that. I think it was largely the compiler that helped make it easier.

I think have 10 more years of programming experience probably makes it easier to pick up a new language
I'd argue that your parent is right. In the superficial sense, of learn the syntax and can spit out code.

That said code in C++ would just vomit cryptic messages about templates and SEGFAULT nearly all the time.

What I'm trying to say skill floor - minimum skill/time needed to learn something to do it however in Rust is higher than C++. Although not in the sense of you must be this smart to enter, but you need this much time to learn it. If I can learn it, and I'm a mediocre programmer it's not an issue of skill.

That said skill ceiling - skill needed to do it efficiently and without error is much higher in C++ than in Rust.

Speaking as someone for whom programming is only ancillary to my job and who previously use python as my primary language, I wouldn't touch C/C++ with a 10-foot pole simply because I don't trust my own abilities to not screw it up and don't have the time to put into learning them to a level where I know I'm not.

Things that Rust does that makes things easy for me as a less-experienced non-systems programmer:

- very good documentation and compiler errors

- cargo makes dependency management and distribution a breeze (big plus over python)

- footguns are easily recognizable and avoided (unsafe)

- strong typing allows me to express more invariants in the type system which makes my code easier to reason about (another big plus over python)

The borrow checker can be an impediment at times and I'm probably leaving some performance at the door by generally avoiding references in data structures. I've found that this is less of a problem over time. It can also be way more verbose. But I have way more confidence that things will work at the end of the day, which makes it worthwhile for me, even if on the surface it is take longer and be harder to write than python.

Rust isn't actually that complicated and more importantly, most of it makes sense. I don't feel the same way about C++.
I feel that C++ makes sense.

It doesn't actually make for a good argument.

C++ makes more sense to me than Go or PHP. And probably Python.

There is C++ code that 99.999% of people that list C++ in their resume are unable to explain.

You can get comfortable with some idioms of C++, that's fine. Can you understand what any valid C++ code means? No. Such person does not exist, not even Bjarne.

You can say the same of any language. Deobfuscation is a hard problem. Only code meant to be reasonably understood is a valid comparison.
I don't mean obfuscation, I mean features of the language and their interactions.

C++ is a mine field. You need to learn where all the mines are and spend your day carefully walking around them.

Sure, but that's not what you said. If what you meant is that there is no one that can read anh more or less reasonably written code in C++, then I believe you'd be wrong.
For the vast majority of programmers who don't know either. learning how to write correct Rust is easier than learning how to write correct C++.
I was scared of C++ but Rust offered me some confidence to start.

Some languages (like C) are easy but using them is hard.

Rust exists in a way to point out that C++ is waaaaaaaayyyyyy harder than it looks.
Cargo is the number one feature of Rust that makes it easier for a newbie to use. New users of C++ struggle the most with building and linking projects together. Cargo makes that newbie proof. Source: I teach C++ and Rust to new programmers, and they almost universally get further, faster with Rust than C++.
I concede that the Rust tooling is miles ahead no question.
Meson has improved the build situation in C++ significantly.
Kind of, but it also exacerbates one of the problems with C++ build systems which is there are so many and none of them are the build system. On one hand this is desirable from the perspective that it avoids monoculture. But it's a bad thing from the perspective of a new programmer in that it causes a lot of confusion and a form of "choice paralysis", where programmers become overwhelmed by options and choose nothing out of a fear of making the wrong choice.
Time to write a program that compiles and seems to do what it does: Takes ages longer in Rust, unless you're experienced.

Time to be reasonably sure your multi-threaded code won't crash randomly: Takes ages longer in C++, even if you're experienced.

It's not _that_ complicated these days. structs, classes strings, vectors, hash maps, unique_ptr, references, non-owning pointers where it makes sense, basic templates. Boom. You also need basics like ownership, order of construction/destruction, value categories, move semantics, special member functions, RAII, etc. All the fancy perfect forwarding and template magic are wrapped up in libraries most don't need to think to hard about. Most people rarely write code that actually manages resource lifecycle directly. It's all wrapped up in RAII.

If you read the whole spec, it looks super complicated. But getting to a mental model that works in 99% of cases is not _that_ hard.

Cause those person-hours have to come from somewhere.

Am I spending 2x of the new hire's time making them learn a harder language? Am I spending 2x of a senior's time teaching the new hire?

What's the payoff in sticking with C++? Better libraries? Better tools? IDEs? That stuff will all shift as time goes on, if popularity is against it.

My point was a good coder / CS person is going learn either twice as fast as average one, bad one not at all.
Robert C Martin's book about software architecture made a point about the fleeting nature of software as a product.

Time goes on, business changes and computers become faster.

At some point, many developers started to see features like a garbage collector, become a good offer with few disadvantages.

Unless we really need the performance, do users really care if the program consumes a few cycles more, if those cycles are being spent on tools to make lives easier for developers, like a garbage collector?

90% of software wouldn't make sense to be written in C

What's the equivalent in Rust to Eigen, Ceres Solver, OpenCV, JNI and Qt UI bindings?

This is my standard stack for C++ and last time I checked Rust couldn't do any of them. This is also my standard stack for building new open source computer vision libraries, growing the available libraries and making my field more locked into C++, increasing the moat Rust would need to cross.

Next step, can I compile and deploy for Windows, macOS, Linux, Android and iOS? All of these are critical business requirements. This is whether I can adopt Rust in my employer's codebase.

Finally, can I easily find and hire engineers who can read and write Rust who aren't asking FAANG compensation levels? This is the blocker for Rust in startups.

Deploying for Windows, macOS, Linux, iOS and Android is way easier with Rust than C(++), because there's one build system and one standard library that supports them all without #ifdefs. The ecosystem takes first-class Windows compatibility seriously instead of having a unix and windows dialects and the unix side saying MS sucks and it's your problem it doesn't compile.

The worst part about Rust's cross-platform compatibility and cross-compilation is Rust's dependence on a C linker and C/C++ dependencies if you choose to use them.

Modern C++ has cross platform threads, filesystem access, etc. Unless you're actually trying to use platform specific technology, there's no need for #ifdefs.

For the most part CMake handles the cross platform toolchain issues, so it's just one flag to turn on Release Vs Debug builds, enable LTO, include dependencies etc. Again, it's just platform specific features that require if...endif sections.

The complaints I'm seeing here would be the equivalent of me complaining about Rust's garbage collection, the only difference is that Rust broke everyone's code in removing it while C++ managed to keep almost everything since the 1980s still working.

Because “just hire good people” is on par with “just hire good pilots”. Easier said than done.
It's also expensive. Every industry has focused on changing the environment so average people can do good work rather than fight over the top 5% of talent.
I guess Java would be the counter example to this.
Um no. A closer analogy would be like hiring a good 737 pilot for 777 instead of someone with thousands of hours on the 777.
This is a common fallacy imho that if I am a good dev, I can easily cross-train.

I have been writing C# almost exclusively for around 20 years and I am still learning tricks/tips/gotchas and not just for new language features. That is why my experience is important. Even in something like Java which looks very similar to C#, it takes a long time to work out what works differently, good patterns and idioms, the correct libraries that everyone uses for stuff etc. even when I know what I am looking for.

When I looked at Rust, I got some of it because I have previously written C and C++ and didn't have a problem with the concept of pointers or references but it still took me several weeks to get a basic example working and I had to ask on a forum in the end.

So yeah, not easy!

I mean I could learn C++, but I don't wanna. I did some of it back in school (game development) and I don't particularly care for it. I don't want to do memory management myself or even have to worry about it.
Ok, so I hate to be too direct but the rust enthusiasm always struck me as annoying like the meme about arch users telling everyone they use arch and so should you, but on that token, I always felt it strange given it's literally over something as mundane as a programming language choice. BUT, this as a reason seems to explain a lot more for why evangelists, particularly those in management type positions in large IT companies are pushing rust so much. Wanting to weaken the economic position of a certain type of developer makes a lot more sense.
> Wanting to weaken the economic position of a certain type of developer makes a lot more sense.

Just more anecdata, but this isn't true for my company. We're hiring for Rust because we're seeing more and more clients take memory safety seriously (and ask specifically about it as a design consideration).

These things have a way of balancing themselves out: developers like Rust, so there will probably be an eventual "glut" of Rust programmers like there was for C++ programmers in the 1990s. But it's a multiparadigm language, so I don't expect there to be consistent wage deflation based on that (and especially not in systems, where finding competent engineers is a perennial problem).

> we're seeing more and more clients take memory safety seriously

Running your test suite with asan, msan, tsan isn't sufficient? From my experience you need to start doing really nasty things (which shouldn't pass code review) before the sanitizers won't find your issues.

There are plenty of things that ASan won’t catch, like misuse between contiguous allocations.

But that’s sort of tangential: the goal is to write software that’s correct to begin with, not poke holes in it with the testsuite after the fact. With Rust, I can pick third-party dependencies that I can be (vanishingly) confident don’t have memory safety issues; when I start a greenfield C++ project, any dependencies I bring in are now potential sources of memory unsafety in my code.

Do you vet all of your dependencies' code for unsoundness when using unsafe?
One of the guarantees that Unsafe Rust makes is that well-formed unsafe code cannot trigger unsoundness in safe code.

In other words: I very rarely write unsafe code myself. When I bring in others’ unsafe code, I use cargo-geiger and siderophile (which I help maintain) to quantify it.

It's not a guaranteed guarantee as far as I can understand.

Or such bugreports would make no sense: https://github.com/denoland/deno/issues/15020

The bug report says exactly what I said: if you don't write well-formed Unsafe Rust, then Rust will not make any guarantees about invariant preservation in Safe Rust.

This is exactly the same as in C++, except stronger: in C++, any piece of well-formed code can violate safe invariants. In Rust, only unsafe code can violate safe invariants, and can only do so if it isn't itself well-formed.

According to the RustBelt paper [0]:

> so long as the only unsafe code in a well-typed λRust program is confined to libraries that satisfy their verification conditions, the program is safe to execute.

I think the main caveat is that IIRC, the RustBelt unsafe rules do not cover ALL uses of unsafe in the wild, they analyze only a subset of Rust as whole, and of course, unsafe usage actually has to obey the rules. But I'm hardly an expert here.

That bug report basically says they broke the unsafe rules and thus the guarantee no longer holds (and there is UB).

[0] https://dl.acm.org/doi/abs/10.1145/3158154

I'm reminded of this quote, written in support of more and stronger use of systems for formal verification, like powerful type systems:

> Program testing can be a very effective way to show the presence of bugs, but it is hopelessly inadequate for showing their absence. -- Edsger W. Dijkstra, "The Humble Programmer" (1972)

Oh for sure, use better types to express the problem in ways that the compiler can catch mistakes. But... you do need to show at some point that your code actually does what you claim it does, even if just for a single use case; might as well piggyback sanitizers since you're running tests anyways.

Re: Dijkstra, I'm not trying to prove that the code has no memory errors, I'm trying to make sure none get triggered in production ie. the difference between computer science and software engineering. If there was a simple and easy way to do behaviour proofs I'd be happy to use that, but coq et al. are a real pain.

No Rust Evangelist is out there thinking, "Hm, how do I put C/C++ developers out of business today"
I see you do not have much contact with Rust evangelists.
I think they're thinking "how do we get those C++ businesses to switch to Rust" rather than "how do I bankrupt them".
They're thinking "how do we get those C++ businesses to stop hiring C++ coders, and start hiring us Rust coders instead".

The original purpose of Rust was to displace C, a laudable goal. But it is failing at that, because C coders are practically defined as people who will never switch to anything. (Any who might have did already.) So now the only hope is to displace C++ instead, and the propaganda machine is trying to paint C++ as equally as unsafe as C, which it manifestly is not, lying if that is what it takes.

Well, there is corporate financial interests involved, which is sure to push the propaganda machine into higher gear. Expect a lot more trash and FUD being thrown around by converted fanatics and speculators, in regards to all the "inferior" languages.
What issue is there for the C++ developers to transition?

Rust is a simpler language, with better characteristics. Memory safety is the a big selling point for the business people, but there is also a better module system, dependency management, better generics, no hidden memory allocation, etc. etc.

> What issue is there for the C++ developers to transition?

rust is lacking a ton of libraries.

And personally I prefer using a big thing like Qt which has classes for everything, rather than rust where I have to find a non-terrible library for every little thing.

Rust is not, in the end, a simpler language, in the same way C is not. It is able to do less, which leaves me needing to do more.
"Hey C++ developer, you should use rust instead" is very different than "Hey C++ developer, I don't want you to have a job".

Do you not see the difference?

I do. "New programs should not be in C++" means, exactly, "You should be laid off so they can hire me instead". If you had something that could do what I need, I would be using it already. It cannot. But you want to bypass me and fool managers, instead, with FUD about memory faults I don't code and have not in years.

I have spent strictly more time in the past five years filing compiler bug reports than chasing memory faults. Yet you say I should trust the compiler to make errors impossible. Are you able to see the flaw in your reasoning, here?

> "New programs should not be in C++" means, exactly, "You should be laid off so they can hire me instead".

That strikes me as wrong in many ways. I think it means, exactly - "new programs should use a different language than C++".

I someone writing that might have been implying "hire me instead", but given the specific author is CTO of azure, i doubt they are angling for your job, or really any dev job.

Managers hearing this advice from the CTO of could possibly interpret it as "lay off our C++ folks, we're hiring for rust". Or they could interpret it as:

* We should switch to the new language, have the team train up.

* We should have the team start evaluating new languages (or rust specifically).

* We hire some rust folks for the next project to evaluate how it goes.

Any half-way decent management will know that the institutional knowledge in their existing dev team is worth a lot, and getting the new hires up to speed is rather expensive.

Sure crap management exists, but I've never had, nor known any who has had management so bad that they would lay off thier whole dev team over a tweet. I really doubt "lay off all the C++ folks" would be a particularly common response.

The topic in this subthread is overbearing Rust evangelists and their effects.

To the degree that management pays them any attention -- and a CTO parroting their advocacy in tweets (squawks?) certainly counts -- the threat is real. Other companies' management may be equally affected, in a degree more than just posting idle-hack tweets.

Against, the subthread topic is overbearing Rust advocates and, specifically, what harm they can do. Obviously nobody will "lay off all the C++ folks" just because Rust promoters would really like that, and as much as say so. But that is very far from saying no harm is done, or that no one is harmed by their extremist rhetoric.

> Obviously nobody will "lay off all the C++ folks" just because Rust promoters would really like that, and as much as say so

1. If it was so obvious, why did you claim it to be true, and then double down?

2. I have yet to see anyone say or even strongly imply it. The closest I've seen is this thread wherein you take a lot of leaps in reasoning and a very specific path through a large possibility space to divine the true intent of a simple sentence.

It is one thing for people to advocate a thing, such as "you should fire all your C++ staff and hire us", and another thing for my employer to obey.

But that difference does not make advocating it less bad, unless they are obviously speaking facetiously and expect it to have no effect. It is very clear people saying it mean it and want that to happen.

Azure CTO's announcement is a success for that advocacy.

I think you are delusional. No one is advocating for your firing. "NEW projects" is not "all projects ever existing". Just like cobol is still there and running decades after it was first considered a dead language. Even after new projects were all being written in java, the cobol programmers were there. They switched languages, or kept working in cobol. There are still new cobol programmers in 2022.

Even if every C++ codebase wanted to rewrite itself in rust that effort would take decades and in the mean time we'd still need C++ devs.

The only people advocating for firing C++ all devs are the imaginary ones in your head.

Calling people delusional means you have no argument.

If my employer announced no new C++ projects, that would mean, at best, a sharp demotion. I would be relegated to maintenance of legacy products. The kind of systems I make would no longer be written, because Rust is not up to the job.

You reveal that what you are doing is fully as nasty as it seems. You reveal that you believe there wil be no room for your language without first tearing down another.

Have you even used Rust? Based on your other comments, it just seems like you have an axe to grind against anyone who uses Rust, coming up with accusations of "Rust devs trying to take 'er jerbs"
I like Rust fine. But Rust is not suitable for my work, where C++ is.

So, anyone saying "no programs should be written in C++" is saying, exactly, that I should not be able to do my work, and that I should not have employment.

That my current employer will not necessarily obey such an instruction does not make the attempt any the less offensive.

It's finally clear - You don't actually think that people are advocating for you to be fired[1]. You are just taking an absurd extreme position because after a career of not having to think too much about other languages something comes along that can actually threaten the C++ crown. Now you are worried that you'll be relegated to the niches along with your language, like assembler and cobol. Don't worry - there'll be room for you there even as C++ fades away: you can stay in the niches, or you can maintain the mountains of existing C++ code, or you can evolve and move forward with the rest of us.

You are a great case study in why the rest of us shouldn't comingle our identities with the identities of our tools.

[1] I did note that you changed it from "no new projects" to "no programs" a dirty trick that I'm only going to address by pointing it out.

Try to explain the difference between "no new projects" and "no programs". Any program I have not written yet would be a new project. Any old project is one where the program has already been written.

So you are being dishonest in pretending to a distinction without a difference.

Switching from the legitimate "you should use my new language because it is good" to "you should demote everybody coding <otherlang> to legacy maintenance, and put us in their place" admits a very ugly fact about yourselves and about your beliefs about your language's legitimate prospects.

If you believed it deserves a place on its own merits, you would not be trying to tear down other languages to try to make a hole for it. It is disgraceful behavior.

You should be ashamed of that, and you should be more ashamed of calling people who object "delusional".

> Any program I have not written yet would be a new project. Any old project is one where the program has already been written.

That is simply not any definition I've ever heard for a new project. You are assuming a binary of written or not written, and yet there are codebases that are incompletely written. That is what the parent means about ongoing projects that wouldn't migrate to Rust where you'd still be able to work on them, and who knows, maybe Rust won't overtake C++ and it'll continue, like many C projects have.

But that you have made yourself a "C++ developer," and not a developer in general who solves problems with whatever tool is best, does mean that whenever something comes along that threatens your identity, you seem to take it to absurdity, as the parent says.

You have already revealed your true colors.
No, more like you have, as others have pointed out.
(comment deleted)
I love that you can't accept the possibility that Rust is good so much that you had to come up with a genuine conspiracy theory to explain its popularity.
Surely you're joking, because I simply refuse to believe that you think Rust developers are actually sitting around thinking how to put other devs out of a job instead of, you know, using Rust simply because it's a better, more well designed language.
I didn't read it that way at all.

I read it as: where can we find a lower cost (than C++) pool of developers.

It's not particularly conspiratorial. Companies are always looking to expand their labor force and good C++ devs can be very expensive, so why would you want start a new project in C++? Security is another aspect altogether...

Companies don't care about cost, they care about bang for the buck. And this is where Rust has a clear advantage over C/C++, at least in many cases.
I'd actually prefer a GCed language, but Rust gets so many of the other things right that its still better than anything I've seen before (despite forcing a borrow checker on me).
Buggy whip manufacturers were also concerned that the car was just a conspiracy to drive them out of business.
You can find good C++ devs, if ySegmentation fault.
(comment deleted)
Yep. C and C++ devs, Rust really isn't for you; it's for your replacement.
Ahhh, okay, good. Am in the process of learning it, but I think I'll stop and get ready to be replaced instead. After all, being in my 20's, ive become too old to "get it".
Has he ever heard of kernels or device drivers? Probably not.
Most likely yes, check SysInternals and Windows Internals books.
Love this comment so much. Almost ranks up there with the one where someone tried to explain to cperciva about that award and he was a recipient.
Hey, could you please stop posting unsubstantive comments to HN? You've been doing it a lot, unfortunately, and we have to ban that sort of account because it's not what this site is for and destroys what is for.

If you'd please review https://news.ycombinator.com/newsguidelines.html and stick to the rules when posting here, we'd appreciate it.

Inside Azure there’s an over reliance to C#, and the older versions of it to boot! So one team in charge of making .NET run faster and better, while the other one drags on using decade old versions

Then for “speed” there’s weird mashups of C++ and C# that are just littered with terrible internal build tools that harken back to a nice 2010s and the idea of:

“Idk it builds in my machine just fine”

As far as Rust goes, it’s as plentiful as F# projects (so not existing).

But that’s just what my close friend says at least.

This ^^

Really, anyone senior in Microsoft shouldn't be making this sort of argument. They already have a perfectly fine memory safe language that they could use way more widely than they already do. The number of bugs in Windows that either shouldn't happen or are too hard to debug when they do, because Microsoft insist on still using C++ instead of C#, is just phenomenal. Why can Google ship a mobile OS in which large chunks including the entire GUI layer run on a JVM, but Microsoft can't ship memory safe code in Windows for even the non-performance sensitive parts because they have some irrational fear of C#?

The issues there are obviously cultural. If Rust is hard-man enough to convince Microsoft devs to adopt it when they otherwise reject C# then fine, whatever, do what it takes. But to generalize this to the rest of the software industry is silly. Most of us have been writing code in memory safe languages for a very long time, and they could be used way more widely than they are. If you want to make more code memory safe you'd be better off advancing .NET ngen or JVM AOT at this point than pushing Rust, at least they can handle arbitrary data structures in safe ways.

> Why can Google ship a mobile OS in which large chunks including the entire GUI layer run on a JVM

I'm sorry but what the fuck. I paid my fucking phone 1k€ and yet it's bewilderingly slower than a RPi4 with a native apps stack. Every single interaction in the UI is slow and has some amount of lag, even with a 120fps screen. Android is to me the very best argument against Java there is - who knows how many tens of thousands of man-hours spent into optimizing it and it just does not perform to any acceptable level even with best in class hardware. It also has the most app crashes I have seen on any platform.

The volume of existing C, C++, Objective-C, and C# code is phenomenal. Even if this strategy is generally adopted there will continue to be lots of this legacy code for many years to come. In particular there will continue to be such legacy code right up until 2038 at least.
The old C/C++ and other code in popular languages is forever with us. Look at what happened to COBOL, it's still relevant and IMO, will be relevant in 20 years.
carbon, and the newly announced alpha stage efforts called cppfront, can potentially act as a "typescript" for c++, new compiler can enforce memory safety at an upper layer before they're converted to c++, maybe there is hope for c/c++ code for years to come as long as they keep fixing issues along the way.
Having written enough Rust code, I could bet that it won't be an easy task to rewrite C/C++ code with a borrow checked language. You just need to write code differently for this approach to work.
This is kind of the argument though. People are likely to migrate existing code if it’s easy enough. If they have to rewrite the whole thing, then it’s not often going to be done.
Is anyone attempting to do the same with C though? Carbon & cppfront, if successful, would only "save" C++. C would still be left out to dry. Then again, the C committee is also pretty much phoning it in and has been for quite a while now.
Yes. Microsoft Research is working on "Checked C": https://www.microsoft.com/en-us/research/project/checked-c/

As a test, someone ported FreeBSD's networking stack to Checked C. It was easy and there was no overhead to performance and binary size.

That's pretty interesting. It really undersells itself in the intro description where it sounds something more like clang's ubsan -fsanitize=bounds, but in actuality it's adding other features as well including generics. Although that said, it's somewhat odd that memory lifetime is entirely ignored by it. All the changes seem to be laser focused on bounds checks and bounds checks only (with generics being to eliminate `void*` specifically so that, you guessed it, bounds checking can be done)
> Is anyone attempting to do the same with C though?

Absolutely. In fact cfront preceded cppfront by many years ;-)

There is still shitloads of COBOL code in use. And we still consider it depreciated and not suitable for new projects.
"for those scenarios where a non-GC language is required"

C# code is out of scope for this discussion.

Even more of a reason to implore a moratorium immediately.
Is he actually doing it? Making a plan and a policy to replace the bone marrow of MS with Rust? Or is this just a pie in the sky tweet? I don't know what Mark is like as a CTO, so I really don't know what to expect here.
Which part of "new projects" did you miss?
He stopped reading after Microsoft with his head racing hard to somehow bring them down
Without a roadmap, plan, and policy, I read this as a "maybe someday" tweet. Seems like something Elon Musk would say.
> I really don't know what to expect here.

I do. This is Microsoft.

LOL... Two of the most successful Windows tools I've seen in a long time are both written primarily in C/C++. Winget and Windows Terminal. Please let me know when Microsoft has a major Rust-win, because so far they haven't.
Can you even use Rust for Windows GUI programming? Is it a practical choice at all for interfaces?
GUI code is fine with garbage collection. So it still fits with his message.
In theory yes, but there's a lot of quirks and limitations.

The main issues are:

- Rust string types assume UTF-8, but Windows generally uses double-byte Unicode encodings. The Windows string type isn't even UTF16, because it can include invalid code points. This means that at every API call there will be the overhead of converting the string encodings and having to "deal" with invalid strings somehow.

- Rust compilation is still very slow. In C++, it was a simple matter of including "windows.h" and then start typing code. In Rust, trying to do this naively would result in terrible "inner loop" for the developers. There are some fixes, but they're fiddly.

- Enormous API surface with missing metadata. This is a problem with Rust-to-C interop in general, but the Win32 APIs are so huge that it's impractical to solve manually. There have been efforts by Microsoft to produce official and authoritative interface definitions with additional metadata such as tagging "in" and "out" parameters, etc... This isn't sufficient for Rust, which has a much more complex type system than vanilla C pointers. E.g.: lifetimes, non-null by default, etc...

At this time, programming in Rust for Windows is basically writing C++ code in Rust syntax, but with a slower compile time than C++ would have. Arguably, there isn't even much of a safety benefit, because that would require an extensive set of "shims" to be produced to make Win32 act more like Rust and less like C/C++. Take a look at the size of the .NET Framework standard library to get an idea of what that entails. Not impossible, but not a trivial effort either!

The best and most authoritative bindings are: https://github.com/microsoft/windows-rs

The "demo" looks okay at first glance:

    unsafe {
        let event = CreateEventW(None, true, false, None)?;
        SetEvent(event).ok()?;
        WaitForSingleObject(event, 0);
        CloseHandle(event).ok()?;

        MessageBoxA(None, s!("Ansi"), s!("Caption"), MB_OK);
        MessageBoxW(None, w!("Wide"), w!("Caption"), MB_OK);
    }
But if you start digging deeper into callbacks that manipulate structures that include hideous things such as lists of strings separated by null bytes, you're back in "the weeds" just like with C/C++.
Pretty sure most win32 now has an alternative utf8 function?
No, they don't. We typically use the UTF-16 functions (with the W suffix).
I tried to spin up a project with the Microsoft Rust bindings but for what I needed (DirectX12) there’s a lot of necessary helpers in the header files that haven’t got ported over there. And working from one of the samples it was nowhere near as reliable as the C++ version. Beyond ‘oh the C++ code isn’t catching errors’ - every HRESULT was checked as it was using the WinRT bindings.

Kenny Kerr has done an excellent job with both the C++ and Rust bindings, but the Rust one isn’t there yet.

What I’d like to see is more use of a WinMD style metadata for the ABI for functions in DLLs you create. It would be quite simple to define a Span type that could then be imported and called safely from a diverse range of FFIs. I really shouldn’t be having to declare the ABI all over again with ctypes in Python.

I disagree with the "excelent job" for C++.

Using C++/WinRT is like going back to developing COM with Visual C++ 6.0, but I guess that is what WinDev craves for.

They should have provided a proper development experience for IDL files, automatic merges of generated code, and only then, deprecate C++/CX.

Not deprecating C++/CX, and leaving us with editing IDL files with a Notepad like experience, and manually merging generated code.

Rust/WinRT is even worse in regards to WinUI tooling.

I'd imagine that he would recommend C# for GUI programming.
No, it isn't. Yes, you can make Windows or macOS or Linux GUI in rust. Yes, there are options, but:

- ecosystem for GUI is weak

- Can't' imagine using anything, but relm or gtk-rs

- Existing GUI paradigms don't work well in Rust at all

As much as I love writing rust, I would rather write "core" in rust and link with it from something else for GUI.

Unless he means that Rust should be used on projects where the Rust compiler is available for all relevant platforms and C and C++ can be used otherwise, I disagree.

In fact, until LLVM is replaced, C++ will probably be the language of choice for new languages. Even `rustc` requires a C++ bootstrap for that purpose.

There are also other important C++ and C libraries that will continue to mean C and C++ may be better choices than Rust in certain cases.

And don't get me started on embedded.

Also, that doesn't even matter when the purpose is a hobby project (such as mine) where the programmer has no interest in Rust (such as me).

I like how Trevor Jim put it [1] better:

> If you decide to write your project in C/C++ you must have a plan for handling the inevitable memory corruption in advance. Anything else is malpractice.

This is possible to do. I've released a non-trivial program that has had no known memory bugs ever since 1.0 on 2018-10-26. It is written in C. And I challenge anyone to find one in any release since then. You might find one, but I think it will be tough.

In other words, it's possible to put C and C++ on the same footing as Rust when it comes to memory bugs; after all, even Rust is not perfect there.

Yes, it takes more effort. A lot more effort. For my hobby projects, that works fine because I'd rather work in C with the extra effort than in Rust.

Oh, and it's possible to make C as good as Rust: I've got macros to do automatic bounds checking. I've got RAII and stack traces. I've got structured concurrency, which will give the same capabilities as the Rust borrow checker if you adjust your coding style. And all this in portable C11.

So no, Rust is not the end-all be-all of languages. Sorry.

Rant about absolutist opinion over.

But seriously, use Rust if it's available for your target platforms, and you have no other preference.

[1]: http://trevorjim.com/using-an-unsafe-language-is-a-design-fl...

If we are offering absolutist opinions, I would like to offer a counterpoint.

>I've got macros to do automatic bounds checking. I've got RAII and stack traces. I've got structured concurrency, which will give the same capabilities as the Rust borrow checker if you adjust your coding style. And all this in portable C11.

You can do this all in C but it is an absolute nightmare. Every large C program grows some strange bespoke and incompatible versions of all that stuff at some point. And they're all a pain to use because none of it is idiomatic to the language. It's seriously awful. Things like the Linux kernel are the worst offenders. I will be happy when the C language finally reaches the end of its miserable, slow, agonizing death.

I understand you think it's awful, but I do like it. Everyone has their preference.
You can like something and still admit that it is awful. I "liked" C for a long time before there were better options...
I still disagree that it's awful.
The argument you are missing: Your position is bespoke and incompatible. You don't use idioms in your C code. You use idiolect. Thus, you exist in your own universe and are a party of one.

And the clue was something you might not expect...

I programmed C++ for five years, and C for over ten years before that. I don't know rust, but I followed this discussion with great interest.

One of the topics that came up several times was being able to identify who wrote what C++ code based upon their choice of language subset without using blame.

In the pro-rust arguments and C++ counter-arguments and rust counter-counter-arguments and C++ counter-counter-counter arguments in discussions above yours, I was pleasantly surprised to see that grandfather comments were rarely (never?) the same author. At least the rust and C++ arguments were made by different people sharing some sort of group mentality.

Then I hit your thread and saw the grandchild comment: "I understand you think it's awful, but I do like it. Everyone has their preference." and I was like: "Okay. I bet grandparent is also ghoward."

The simple fact that no one is chiming in to grandchild your arguments is the point that you're missing. In fact, the entire subthreads you've spawned involve basically ghoward defending ghoward's position.

It's nice when other people can take over your work. That's what we're after.

It's not lost on me at all.

I prefer to finish software. [1] I get it to where it needs to be and put it in maintenance mode.

I don't accept outside contributions. [2]

I prefer to work alone to keep the scope of my software manageable and to reduce communication overhead. And to avoid working with people. People are too complicated.

I obsessively document my software. [3]

I comment all of my code. I wrote design documents and requirements lists. I write documents about the source code, its concepts, and how to understand and read it. I turn my code into something that can be studied and used far into the future.

Most programmers are not like Donald Knuth. But there are a few that are. I'm one of them.

Please let me be like that. Don't make me work like everyone else because I can't; I've tried.

I'm fine if you all want to use Rust. I even said to use it by default in my first post.

You all seem unhappy that I do not want to use Rust. I don't get why.

I'm defending my position because it appears you all think it's not acceptable. You're wrong.

[1]: https://gavinhoward.com/2019/11/finishing-software/

[2]: https://git.yzena.com/Yzena/Yc#open-source-not-open-contribu...

[3]: https://git.yzena.com/gavin/bc/src/branch/master/manuals/dev...

(comment deleted)
I was going to start this reply by saying "I am not necessarily defending / supporting ghoward's position", but after I read his whole reply, I realize I am.

I enjoy writing C (more than C++); I do not find it awful. If you cannot accept that, then there is nothing I can say to change your mind. What I don't understand is this atavistic obsession that "everyone must migrate to rust now", and "C is so dangerous in can explode in your hands while you are sleeping".

Please, go forth and multiply, and use rust to your heart's content. But be more open minded to the fact that there are people who like, enjoy or even love using C. As for me, I admit I have gone from interested in rust, to neutral, to an active dislike, because this narrow-mindedness some of its proponents show.

You do you. Maybe it isn't said often enough, but each side (Rust-lovers and Rust-haters) has to be confident enough to allow others to disagree.

However, let's be serious, the anti-Rust crowd has not been some bastion of high-minded virtue with its flimsy arguments ("Just write better code..." and "Modern C++ doesn't have these issues..."), mole hill matters of taste ("Egads! The syntax!"), drive by hype hate, and unexplained red-herring cul de sacs ("I doesn't have a spec!" Okay, why do you need a spec?).

> I'm defending my position because it appears you all think it's not acceptable. You're wrong.

I'm not sure this and sentiments like it represent something less narrow-minded? Most of the time, it seems kinda resentful?

Because it is. And it is because you all say things that imply people like me are terrible, awful, evil, no-good, very bad people for not using Rust.

We are not. We just have different preferences.

You all have also implied that we are negligent for using C. I don't know about others, but I have not been.

That's why I have the challenge to break a release of my `bc`. I actually have not been negligent because I do put in the effort required to eliminate memory bugs as much as possible.

Until the RESF refrains from implying we are bad or negligent for not using Rust, we will be resentful.

> You all have also implied that we are negligent for using C. I don't know about others, but I have not been.

I’m sorry that people have implied that, but I feel most of the time when Rust people say languages like C should be retired or deprecated, are doing so because your skill and attention to detail does not scale.

Maybe you personally have advanced enough to write safe code, and you have the requisite skills and insight to avoid any and all memory bugs, such that your C code is just as safe as what Rust would compile. That’s great.

But there’s always someone starting out and they will not have your skills. They will make the use after free, null pointer deference, buffer overflows, and other issues that the C language not only allow but encourage.

So the question is: how long do we tolerate new programmers making these mistakes in production code, leading to bugs and exploits for all, when other languages are readily available that would have caught those mistakes before reaching production? C was released 50 years ago, and in the intervening time a lot has been learned about how to write programs, and what language features are desirable in enforcing those practices. We also learned that when practiced aren’t enforced, they aren’t followed. So “just write modern c++”, which is espoused throughout this thread, doesn’t work to make c++ code safer, because it’s not enforced. Not taking advantage of those lessons learned seems like folly, irrespective of how bug-free your particular C codebase is.

> I’m sorry that people have implied that, but I feel most of the time when Rust people say languages like C should be retired or deprecated, are doing so because your skill and attention to detail does not scale.

This is a fair argument.

On the other hand, I wish we had less software so that attention to detail did not need to scale.

For example, I run a Gentoo machine with the Awesome Window Manager and no systemd. The end result is less than 50 processes running after I login.

My machine is powerful, but if I were running Gnome, it would still feel laggy. With this minimal setup, my machine is snappy even when running an update and compiling Rust, Chrome, Firefox, or anything else. (I did have to make my update script renice Portage to the lowest priority to make that happen, but it works.)

Nevertheless, it is good when less attention to detail is needed.

I'm making my own C replacement, and I'm going to rewrite my current project in it when it's done. It will be about as safe as Rust, if not safer because it will not have async/await.

> Maybe you personally have advanced enough to write safe code, and you have the requisite skills and insight to avoid any and all memory bugs, such that your C code is just as safe as what Rust would compile. That’s great.

Thank you.

> But there’s always someone starting out and they will not have your skills. They will make the use after free, null pointer deference, buffer overflows, and other issues that the C language not only allow but encourage.

Yes, they will. But I view this argument as equivalent to "roll your own crypto."

If no one actually rolls their own crypto, then we as an industry will lose the ability to do so, even when we need to. If nobody uses C, then we as an industry will lose the ability to do so, even when we need to.

When I started writing `bc`, I sucked at C. `bc` was so full of security holes.

So what I did was spend enormous amounts of time on the test suite and asserts and then hooked those up with sanitizers and Valgrind. Patterns of bugs repeated over and over.

But I eventually got to a point where I started to get good. I didn't release a 1.0 before that point; I waited until I was good and had done thorough checks with as many tools as I could learn.

I'm currently learning and implementing crypto. I am following the same process, except that I'll add in professional code audits by actual cryptographers, which I have to pass before I release the code.

I'm doing this because someone has to.

> So the question is: how long do we tolerate new programmers making these mistakes in production code, leading to bugs and exploits for all, when other languages are readily available that would have caught those mistakes before reaching production?

We should not tolerate this in production code, but this is a failure of the industry. Why are beginners writing production code in the first place?

This industry grew too fast for its own good. It would have been better if it had had a master and apprentice model. The best programmers would be "masters" (in the sense of master and apprentice), and juniors would be apprentices who would write code under the master until the master thought them good enough to be journeymen (moving up from junior), and over time, such journeymen would themselves come to be recognized as masters, and the cycle would repeat.

If the industry does not do that, we may soon lose the ability to do things we need to do.

(Funnily enough, this is another argument for less software because there will be less people to write production software, and they'll all be good at it.)

> C was released 50 years ago, and in the intervening time a lot has been learned about how to write programs, and what language features are desirable in enforcing those practices. We also learned that when practiced aren’t enforced, they aren’t followed. So “just write modern c++”, which is espoused throughout t...

> This industry grew too fast for its own good. It would have been better if it had had a master and apprentice model. The best programmers would be "masters" (in the sense of master and apprentice), and juniors would be apprentices who would write code under the master until the master thought them good enough to be journeymen (moving up from junior), and over time, such journeymen would themselves come to be recognized as masters, and the cycle would repeat.

I 1,000% agree with this perspective. I also actually suspect that some form of professional licensing and/or personal liability would benefit the industry greatly, in that it would give more power to engineers to decline to build software irresponsibly due to pressure from management. Obviously this would be wildly complicated and there would be (potentially intolerable) downsides, but I do wonder what things would look like if we could revoke the licenses of people who repeatedly exercise poor judgment, or if responsible engineers knew they had the backing of a professional organization when pushing back against management.

The irony isn't lost on me that elsewhere in this thread I said that nobody is coming after your software engineering license if you keep writing C :) And I do realize that would probably be a disastrous idea in practice. But in my mind it's great.

And while I do agree that the industry grew too fast for its own good, this is unfortunately the reality we live in. The need for software has exceeded both our ability to produce it reliably and our capacity for training qualified engineers. So we have countless junior developers writing production code without good mentors. And worse, I think we also have a terrifying number of "senior" engineers who are actually junior engineers with a lot of experience but trapped in a local maximum. I don't know how we fix this.

> By the way, the reason I don't use Rust is because I'm pretty sure I would actually write buggier code in Rust than in C. The reason for this is async/await: I just can't get it. I mean, I do get it, but the rules seem too complicated for my brain to do as safely as I can do threads and locks.

I "get" async/await but I… hate that it has to exist. I avoid it in all of my Rust projects. Partly because I don't want to use it, but also because I've never needed to solve a problem in a domain where it would have been invaluable. So just so you know, I've been writing Rust since right around 1.0 and I've been essentially able to just pretend it doesn't exist. I've never used it, but also I've never had to think about not using it if that makes sense.

> I 1,000% agree with this perspective. I also actually suspect that some form of professional licensing and/or personal liability would benefit the industry greatly, in that it would give more power to engineers to decline to build software irresponsibly due to pressure from management.

I also 1,000% agree with this. In fact, if there is any activism I do within the industry, it's pushing for this.

> Obviously this would be wildly complicated and there would be (potentially intolerable) downsides, but I do wonder what things would look like if we could revoke the licenses of people who repeatedly exercise poor judgment, or if responsible engineers knew they had the backing of a professional organization when pushing back against management.

I don't think there would be any downside other than expensive software. But studies have shown that poor software is more expensive!

The one thing that would complicate it is Open Source, but I think that hobbyists should be allowed to practice and put code up with no vetting, just like an engineer might design a shed for his backyard and post it on a blog without his/her seal of approval.

However, if some company decides to use that shed/Open Source code in a project, that company's certified engineers/programmers should be required to vet it the same as they would do for their own code.

And as for the gatekeeping of certification, I think uncertified programmers should be allowed to program, but under the supervision of a certified programmer who accepts liability for their work because that chief programmer should be checking their work.

> The irony isn't lost on me that elsewhere in this thread I said that nobody is coming after your software engineering license if you keep writing C :)

Maybe a litte irony, but I would probably be harsher on myself than you would think.

I think there would probably be a certification for writing C, one for writing Rust, etc.

So I would not be allowed to program as a certified engineer for Rust, but I could probably be certified in C, even though the certification and standard of care for C would be much harder and have a higher bar, for obvious reasons.

I don't know what the industry would set the standard of care for C at, but I personally wouldn't set it lower than my personal standards. If it was set at that, then my license should not be taken away, even if I were paid to work on `bc`.

But if it was set higher, say at the level given to libcurl or SQLite, then yes, I should lose my license if I were working for pay on `bc`, unless I stepped up.

In addition, if I worked on `bc` for pay, my failure to prevent memory bugs in `bcl` recently (the one where Valgrind was not hooked into its tests properly) should, at the very least, put me in front of a licensure board to explain myself. My recent failure to prevent the double-free on `SIGINT` when running expressions should also put me in front of a licensure board to explain myself.

If any paying user had been caused trouble for those bugs (no one ran into them as far as I know), I should have to compensate them for the trouble and probably lose my license for negligence. I was extremely upset that I let those slip through.

So no, I shouldn't lose my license for using C, but there should be one for C, and I should have at least come close to losing it for the recent mistakes that I would consider near-negligence.

> And I do realize that would probably be a disastrous idea in practice. But in my mind it's great.

I want to hear why it might be a disastrous idea. I can't see how it would be because it would lead to less but better quality software, and if bad software actually costs more in the long run, it would actually save the industry money! So I fail to see how it would be disastrous.

Please enlighten me on this; I have to know the weaknesses.

> And while I do agree that the industry grew too fast for its own good, this is unfortunately the reality we li...

> I want to hear why it might be a disastrous idea. I can't see how it would be because it would lead to less but better quality software, and if bad software actually costs more in the long run, it would actually save the industry money! So I fail to see how it would be disastrous.

My answer to this is probably too large for a reply here, but TL;DR is that software engineering is an enormous, complex field. I do know that there are far more ways to do something like this wrong than there are ways to do it right, but I have no idea what would be the right way. Language-based licensing makes sense, but so does licensing for sub-fields like security-related areas (handling PII, cryptography, even different areas of cryptography), operating systems (Windows, macOS, Linux, *BSD, et al), and large frameworks (Hibernate, Rails, React, etc.). But I imagine in practice things would get real murky real quick.

And it's also something where it could easily become too onerous and impossible to develop software.

(comment deleted)
> I enjoy writing C (more than C++); I do not find it awful. If you cannot accept that, then there is nothing I can say to change your mind. What I don't understand is this atavistic obsession that "everyone must migrate to rust now"…

Nobody is saying this!

In the original tweet, Mark Russinovich said he thinks C and C++ should be deprecated. I believe if you asked him to elaborate on this, he would say he believes we should stop using them when possible. Not "must". "Should". And further, I suspect he'd clarify that he is imploring this of the industry as a whole, and not at the scale of individual developers.

People still write asm, and nobody is coming for their heads. We need people like that! And we will need people who are skilled in C for the far foreseeable future. But the time has come where there exist alternatives to C and C++ which are superior for a very large bulk of their remaining use-cases. He's not scolding individual engineers who choose to continue writing code in a language he enjoys. He's calling for the industry as a whole to recognize this new reality and move forward with the times.

Part of the issue though can be perceived psychological pressure, that can border on being coercive or even come off as intimidation. Kind of like all the "cool kids" are using X, and if you are not, then something must be wrong with you. And while Mark is probably not trying to purposefully create that kind of environment, remember there are powerful corporate interests involved, that probably wouldn't mind some intimidation or unnecessary peer pressure to promote their agenda.
"Oh, and it's possible to make C as good as Rust", do you have some concrete advice documented somewhere? Thanks!
Probably write it in Rust first and make a direct C port based on it? (Or is there a tool do this automatically already?)
Yes, mrustc is a compiler that compile Rust into C code.
I hate to admit this, but it took me a long time to do, mostly because I was not experienced when I started writing code, and the code has been rewritten several times over to get it right.

First off is the code in [1]. It's technically under several licenses, but I can give it to you under the public domain because bounds checking in C is important enough that I'll give it away.

The `y_ARRAY_TYPE()` macro generates a struct that is an array with bounds. Use it like this:

    typedef y_ARRAY_TYPE(uint32_t) uint32_t_arr;
`uint32_t_arr` is a bounded array of `uint32_t`'s.

You can then pass that array to functions and do bounds checks with the `y_i()` macro (for when the struct value is not a pointer) and the `y_ip()` macro (for when the struct value is a pointer).

To implement RAII, the code to do that is in the same repo, but it's...much more complicated: a full stack allocator. I just add the destructor as a parameter when allocating memory, and when the allocation is freed, the destructor is called when it's non-NULL. Then there are functions to allocate and free, but it is always done in a stack, to emulate the real stack.

By the way, the type of destructor is

    void (*y_Destructor)(void*)
and it takes a pointer to the item to be destroyed.

Structured concurrency takes the idea of a thread-local stack and sort of generalizes it across threads. The idea is that each thread has a parent, and that parent is not joined until all of its child threads are joined. All threads form a tree, almost exactly like process trees in Linux.

This means that if you want to have another thread borrow an item, you just have to make sure that thread is a descendant of the thread it is borrowing the item from, and you have a guarantee that the item will never go out of scope before the borrowing thread does.

Sometimes you need to change your code to do that. You can "push" things "down the stack" by passing function pointer callbacks to callees who then create the item to borrow and call the callbacks. Inside the callbacks, the borrowed item will always exist.

There's more to it than that (you can turn a thread tree into a DAG [2], allowing you to turn threads that are not descendants of a thread into descendants), but that's probably good enough to start you off.

[1]: https://git.yzena.com/Yzena/Yc/src/commit/cf4c96b3560d/inclu...

[2]: https://lobste.rs/s/8msejg/notes_on_structured_concurrency_g...

Let's be honest, `y_i(array, 10)` is much less readable than `array[10]`. Sure, you can program with bounds checking, but it's less readable, and less newbie-friendly.
Okay and what about preventing use-after-free and dereferencing null pointers?
Dereferencing NULL pointers: my code is structured such that every function parameter that can be NULL is marked so. And I check those possibly-NULL pointers.

This could also be done with a macro:

    #define y_d(p) ((p) == NULL ? abort(), *p : *p)
Otherwise, the compiler (clang, usually) warns me when a NULL pointer is passed in and I have asserts to catch them.

Even before I had all of this infrastructure, deferencing NULL pointers was not a problem for me personally; it's just one of the mistakes I tend to not make. So that's why I don't have a macro for it.

For use-after-free, I use scopes. My stack allocator has a function that will mark the start of a scope, and I call it when entering a new scope. Then the pointers that are allocated during that scope will all be freed when I call the function to free every item in the scope, but those pointers will also go out of scope, which means the compiler won't let me access them.

It looks like this:

    void
    func(size_t s)
    {
        y_stackallocator* p = y_strucon_stackallocator();
        // Random code.
        // Open a new scope. Notice that the scope is a bare scope.
        // But it could also be an if statement or a loop.
        {
            size_t* sp = y_stackallocator_malloc(p, sizeof(size_t) * s, NULL);
            // Random code.
            // This frees everything in the scope, including sp.
            y_stackallocator_scopeExit(p);
        }
        // Scope has exited; sp is not accessible, no use-after-free.
    }
This is less rigorous than Rust, but I use the principles in Joel's "Making Wrong Code Look Wrong" [1] here. If I have scopes that don't look like the above, they are wrong.

[1]: https://www.joelonsoftware.com/2005/05/11/making-wrong-code-...

Do you have a tool that enforces the use of all of these macros and stuff? How do you know that, for instance, you didn't forget something? Seems like one slip-up is all it would take.
This is where C fails against Rust. I have to use static analyzers to find such problems.

But I do use them, and I also use sanitizers against large and thorough test suites, with excessive fuzzing thrown in for good measure. And I mix all of that with crash-happy code littered with gobs of `assert()` calls that document as many of my assumptions as I can find.

Those help me find about all I can find.

But I'm still writing a language that is as safe as Rust that I will auto-translate my code into when it's done.

By the way, I'm not using Rust because I don't like it. That doesn't mean it's not good, but I really hate async/await, along with a few other Rust design decisions.

I'm kind of picky as a programmer.

Yes, C fails against Rust here, but that's why I put in the extra effort to bring it up to the same level regardless.

> But I'm still writing a language that is as safe as Rust that I will auto-translate my code into when it's done.

Just curious, how do you intend to make it memory safe? By using a garbage collector, automatic reference counting, a borrow checker, or something else?

By structuring the language around RAII and structured concurrency. More details in my great-great-great-great-grandparent post. [1]

tl;dr: If threads never exit before their descendants, and you only borrow an item in callees and in descendant threads, that would negate the need for a borrow a checker.

As for sharing an item across threads and still not having data races, this will be done by implementing something close to Rust's Send/Sync.

There will be ARC implemented by RAII, just like Rust.

Basically, the language will be built around structured concurrency, including the standard library.

Does that answer your question?

[1]: https://news.ycombinator.com/item?id=32907696

Ah, sorry, my bad, I should have read the whole thread in detail first instead of just skimming it. (:

So do you also intend to completely disallow mutation? Because that's the only way I could see this matching Rust's safety guarantees without actually having a borrow checker.

Say, for example, that you allocate a new string, and you take a reference to it, and then you append to that string within the same scope. This triggers a reallocation which will make that reference invalid. To make that safe you'd either need to have a borrow checker (to be able to detect at compile time that the reference was invalidated), or you'd have to disallow mutation (the act of mutating wouldn't actually mutate that string, but create a new one, leaving the old one alone until it goes out of scope).

Mutation will be disallowed in general, yes. It's a bit more subtle than that, but you get the gist.

In my language, there are strings, which are fixed size and cannot be reallocated, and string builders, which hide the actual string behind another layer of indirection to avoid the problem with mutation.

That sort of pattern would be used as necessary to avoid the problems with mutation in the same thread. And Send/Sync would take care of the rest across threads.

After looking at this, honestly, you should just use C++.
Well, you're not wrong, but I hate C++. With a passion.
I get where you're coming from - there are plenty of parts of C++ that I dislike also, but this kind of 'clean up on scope exit' has always been one of C++'s strengths - even before modern c++, and is significantly less error-prone than the solution you present above.
What calls scope exit if there's a break / return / goto between the allocation and the scopeExit invocation?
I have macros for that that I use instead of the keywords. If the keywords appear in code that uses scopes like that, it's a bug.

I still have a lot of technical debt with that, but I haven't gotten to it. However, when I do change it, I'll be able to find all instances automatically with grep.

There's a compiler extension to tag variables with a function called on scope exit. Attribute cleanup. For dubious portability reasons I'm unwilling to rely on it for correctness but it's really useful in a debug build for types where you can detect they haven't been cleaned up.

Change MyType to RAIIMyType or similar in the function to get the checking when using GCC/clang with asserts enabled. In practice sometimes types should drop out of scope without deallocation - return from functions etc. Thinking about it now I should probably apply it by default and use (MyType) to avoid the macro expansion selectively.

Write a full unit and functional test suite and run them with asan, tsan, msan and maybe valgrind. This has caught all the memory bugs before getting to production in my experience.

You need the test suite to verify that your code does what you think it does anyways, the sanitizers are just a nice bonus to verify that it also has the safety you think it does.

Yes, absolutely. This is how I do it.

The test suite and asserts for every assumption are hugely important too. Testing under runtime is important.

> In other words, it's possible to put C and C++ on the same footing as Rust when it comes to memory bugs;

No. This is only true if you don't care about occasional bugs. e.g. hobby projects. But if you're talking about mission-critical or security-critical software, there is a gap - or a canyon - between C vs C++ vs Rust. And no amount of extra "efforts" by the programmer's part can bridge those gaps completely.

The true test of what I said is "show me the code."

The code is my `bc`. [1]

Find a memory bug, any memory bug, in my `bc` after 1.0.

Rust has occasional memory bugs too; I mentioned that specifically. It still happens.

So if you really are correct, break my `bc`.

[1]: https://git.yzena.com/gavin/bc

Yes, let’s ignore the quite literally millions of examples of prior art for memory bugs in C/C++ programs because you believe you’ve managed to build a single-threaded CLI calculator that doesn’t have any.

I know how to call `strcpy` safely. Are we clear to put that back into the Linux kernel then?

Notice that in my first post, I said to use Rust where practical. I never said that everyone should use C.

I'm only claiming that I personally can do just as well in C as I could do in Rust, and that I prefer to work in C, so I might as well.

Break my `bc`.

I honestly don't understand the point of your post then. Are you looking for a pat on the back?
>Find a memory bug, any memory bug, in my `bc` after 1.0.

I'm surprised by this confidence given one of the commits on the first page is "Fix a double-free when using expressions and sending SIGINT". And going through the commit history quickly reveals "Fix memory bugs in bcl" (a value not being initialized) and "Fix memory leaks in bcl" (missing dealloc), all within the last two months and all which are trivially not a problem in Rust.

Rust is perfectly happy to leak. But as in C++, there is no temptation to.
Notice that I said to find a memory bug in a release, not just any commit.

Yes, there will be memory bugs during development, but I usually find them before release. There will definitely be commits fixing memory bugs during development.

The bcl library is an exceptional case, where my test suite did not have sanitizers and Valgrind properly hooked up, and that one was because it went from a global (guaranteed to be zeroed) to allocated.

But I also said to find one in the program, not the library.

I issue that challenge again: find a memory bug in the `bc` or `dc` program in a release after 1.0.

Oh, and the double-free with `SIGINT`? Rust isn't going to help you much there. Signals are not part of Rust's model.

>Notice that I said to find a memory bug in a release, not just any commit.

You did not say anything of the sort.

>But I also said to find one in the program, not the library.

You did not say anything of the sort.

You said:

>>The code is my `bc`. [1]

>>Find a memory bug, any memory bug, in my `bc` after 1.0.

>>[1]: https://git.yzena.com/gavin/bc

But okay, let's acknowledge the moved goalposts.

>I issue that challenge again: find a memory bug in the `bc` or `dc` program in a release after 1.0.

Tell me what subset of the repo named "bc" you consider to be "the program"

>Oh, and the double-free with `SIGINT`? Rust isn't going to help you much there. Signals are not part of Rust's model.

Crates like tokio::signal allow a signal to be converted to a stream of events, which can be handled along with any other events in the program, instead of interrupting the current fn in the middle and necessitating longjmp shenanigans. Since the existing stack is not interrupted in any special way, dtors fire as they're supposed to.

> Tell me what subset of the repo named "bc" you consider to be "the program"

Clearly, the parts where you aren't able to find memory bugs.

Anything built without the -a option to configure.sh. You can try the library too, but I did mess up that one time that you already know about.
Okay, so I didn't say a release at first, but I meant to. That's only fair.

Anything built without the -a option to configure.sh is "the program." That's the vast majority. You can try the library too, but there is that one mistake you already know about. I don't think there are any others though.

And again, even with the things you all have found that are in random commits, it doesn't really matter; Rust isn't completely memory safe either. It's close, but not quite.

I realize I should answer the signal part.

tokio::signal-type code would not work for `bc` signals.

`bc` is a special program; most programs are I/O-bound, but `bc` is both I/O- and CPU-bound. And it's interactive, so it's got to respond to the user as fast as possible.

It's quite possible for a user to enter an expression, not realizing how expensive it is to compute (since `bc`'s numbers can be arbitrarily large). In that case, a `SIGINT` should be responded to instantly.

Turning signals into an event stream to read would not do that because the signal handler literally has to `longjmp()` out of itself.

It won't `longjmp()` out if it's not safe to do so, but it can be safe to do so. And when it is not safe to do so, it will set a flag and return normally.

Then the code that wasn't safe to jump around finishes, it will check the flag and jump itself once it is safe.

This is what keeps my `bc` responsive even if you have a long-running computation.

To see this, compile and run my `bc`, and give it this input:

    >>> 2^2^32
It will hang because it's calculating a LARGE number.

Press Ctrl+C. It will instantly return to the input prompt.

I might be wrong that tokio::signal cannot do that, and if so, I apologize. But it doesn't appear so from your description.

Also, I have the same sort of code in my new project to turn signals into an event stream in C.

"Find a memory bug in this repo. No, not those bugs. No, the ones in that part of the program are off limits. The ones I pushed but caught just before tagging don't count either because I noticed them just in time. Okay there was this one time where it happened when my complicated sanitizer setup broke without me realizing but that was a total fluke. And that other one also doesn't count because it definitely wouldn't have been stopped by Rust[1]."

I'm almost tempted to believe this entire exchange was an elaborate setup to convince people to use memory-safe languages.

[1] except I'm… pretty sure it would have been

Seriously?

Just try it. Break my `bc` in a release. I dare you. Until any of you do, you're just trolls or the RESF.

To what end? You’ve already stated elsewhere that your only point is that you can, under an increasingly strict set of conditions, write code that is (almost always) free of memory bugs. Great!

Nobody is hiding around the corner waiting to take `gcc` or `clang` away from you if you want to keep using them. Nobody's threatening to take away your software engineering license if we catch you writing a memory bug.

This whole thread is ridiculous. “The safety improvements in modern cars are substantial. If you're buying a new car these days, you should probably buy one made after 2018.” “Well I'm still driving my 1969 Malibu. Plus I’ve never been in an accident so I don’t need those safety features.” “Okay but… what are those dents in your car?” “I said no accidents on public roads. Prove me wrong or STFU.”

The RESF seems to want to take C away from me. They seem to think I am a bad person for using C. They seem to think I am a bad programmer for using C.

To refute all of that, I point people at some code that they would probably struggle to break.

I'm sorry, but this is an entirely imagined persecution. Nobody is taking your C compiler away from you. Nobody thinks you're a bad person for using C. Nobody thinks you're a bad programmer for using C.

Many of us think there are better alternatives. We're excited about these better alternatives. We want people to use these better alternatives. We think these better alternative solve a lot of problems that many people spend a lot of time dealing with. We think these better alternatives prevent many of the types of bugs that regularly ruin people's afternoons, evenings, and weekends. We really think you should try it out, but if you don't like it, literally nobody is coming to take your compiler away from you.

We do think a lot of the common arguments against moving to these languages are bullshit though. "Rust can't do self-referential data structures" is one of them. "I have a ton of expertise in C and it would take more time than I'm willing to spend to get to that level in something else", "this project is already written in C and mature", and "I write code for unsupported platforms" aren't bullshit, but they are ones that naturally decay in how compelling they are over time.

And as much as I believe you personally can write memory-safe programs in C, I would be willing to bet this guarantee would go out the window the moment you add a second maintainer who can push and release code without you vetting every commit.

> I'm sorry, but this is an entirely imagined persecution. Nobody is taking your C compiler away from you. Nobody thinks you're a bad person for using C. Nobody thinks you're a bad programmer for using C.

I've had people say all of these things to me in various ways.

"You should be ashamed of yourself," is a typical phrase used.

> Many of us think there are better alternatives. We're excited about these better alternatives. We want people to use these better alternatives. We think these better alternative solve a lot of problems that many people spend a lot of time dealing with. We think these better alternatives prevent many of the types of bugs that regularly ruin people's afternoons, evenings, and weekends.

This excitement has been over-the-top and as mentioned by one or more people in this thread, it has actually driven people away from Rust. As much as I don't like Rust, I don't want that to happen.

> We really think you should try it out, but if you don't like it, literally nobody is coming to take your compiler away from you.

When people say they want to deprecate C, that's what they mean. If you deprecate C, the compilers will be abandoned, which in the software world converges to the same effect as taking it away because compilers need ongoing maintenance to keep up with new platforms and such.

If a new platform becomes mainstream, and there's no C compiler for it, then my C compiler has effectively been taken away.

This is one reason I'm making my C replacement language: I do think that C will eventually be abandoned on the major platforms, and I want to have switched by that time.

> We do think a lot of the common arguments against moving to these languages are bull** though.

Which is fair. You didn't say all of them are, and yes, a lot of the common arguments are crud.

> "Rust can't do self-referential data structures" is one of them.

I actually agree with you; this is a crud argument. In order to make my C as safe as possible, I don't use self-referential data structures either; I use a parent data structure.

I did this with linked lists [1]. The linked list is a parent data structure that owns everything, and the items in the linked list just have indices to their neighbors. This allows me to tie Rust-like lifetimes to the items.

And any self-referential data structure can be expressed in terms of a parent data structure and children data structures.

So yes, you are right: this argument is crud.

> "I have a ton of expertise in C and it would take more time than I'm willing to spend to get to that level in something else", "this project is already written in C and mature", and "I write code for unsupported platforms" aren't bull**, but they are ones that naturally decay in how compelling they are over time.

I agree. This is another reason I'm still writing a C replacement for myself.

> And as much as I believe you personally can write memory-safe programs in C, I would be willing to bet this guarantee would go out the window the moment you add a second maintainer who can push and release code without you vetting every commit.

Yep. I agree. Even if it's Linus Torvalds, Ken Thompson, or anyone.

I still vet every commit, or just not accept anything.

It also helps me keep the scope manageable: if I can't do it myself, the scope is too large.

[1]: https://git.yzena.com/Yzena/Yc/src/branch/master/src/contain...

> "You should be ashamed of yourself," is a typical phrase used.

I'm trying very hard to not "no true scotsman" myself here. But I tend to think of it like this: there's people, and then there's Twitter personas. There's a lot of very strong, absurd opinions that Twitter personas have but that I don't ever seem to encounter in the real world.

Maybe another way of putting it is that if I dropped you on stage in the middle of a RustConf keynote, nobody would actually have these types of opinions. And if anyone did express such a thing, there would be overwhelming opposition to it. But of course I can't prove this, and I'd be willing to admit I'm wrong. And none of this discounts the fact that you've apparently seen these types of opinions firsthand.

> > We really think you should try it out, but if you don't like it, literally nobody is coming to take your compiler away from you.

> When people say they want to deprecate C, that's what they mean.

I don't think that's a reasonable take at all. I'd be willing to bet that what Mark Russinovich was saying was exactly what you just stated in another thread: "I agree with this. I never said people should use C by default; absolutely not. They should use Rust by default."

> If a new platform becomes mainstream, and there's no C compiler for it, then my C compiler has effectively been taken away.

Being taken away is very, very different from other people not being sufficiently motivated to build something you want to exist. Nobody has "taken away" COBOL from folks by not porting compilers to arm64 (I have no idea if arm64 COBOL compilers exist, feel free to substitute a suitable arch/lang).

> This is one reason I'm making my C replacement language: I do think that C will eventually be abandoned on the major platforms, and I want to have switched by that time.

I'd be willing to bet substantial sums of money that "eventually" will not include either of our lifetimes. And my guess is it would be far less work to port C to (or write an LLVM backend for) x86-128 or aarch256 or RISC IX than to maintain your own language and keep it running on all the major platforms. But good luck to you nonetheless.

> Yep. I agree. Even if it's Linus Torvalds, Ken Thompson, or anyone.

I'm pleased you pointed this out! I'd debated saying this but opted not to, it's great that we agree on that extra detail.

> I'm trying very hard to not "no true scotsman" myself here. But I tend to think of it like this: there's people, and then there's Twitter personas. There's a lot of very strong, absurd opinions that Twitter personas have but that I don't ever seem to encounter in the real world.

If we expand that to Reddit and Hacker News, I have to agree, so it might have just been personas I went up against.

> Maybe another way of putting it is that if I dropped you on stage in the middle of a RustConf keynote, nobody would actually have these types of opinions. And if anyone did express such a thing, there would be overwhelming opposition to it. But of course I can't prove this, and I'd be willing to admit I'm wrong.

But I've never been to RustConf, so I can't dispute this. I'll simply have to trust you on this one.

Though dropping me of all people into a RustConf keynote would be a wild prank. Hilarious.

> And none of this discounts the fact that you've apparently seen these types of opinions firsthand.

Unless I've only seen personas, as you suspect, and I can't refute that.

> I don't think that's a reasonable take at all. I'd be willing to bet that what Mark Russinovich was saying was exactly what you just stated in another thread: "I agree with this. I never said people should use C by default; absolutely not. They should use Rust by default."

I'm not so sure because I used to be one of the people that thought C should die, as in, have everything rewritten into another language. People like that do exist.

But again, they may just be personas. Whoops.

> Being taken away is very, very different from other people not being sufficiently motivated to build something you want to exist. Nobody has "taken away" COBOL from folks by not porting compilers to arm64 (I have no idea if arm64 COBOL compilers exist, feel free to substitute a suitable arch/lang).

This is a fair counterargument. I guess I should correct myself by saying that it would feel like my C compiler would be taken away.

> I'd be willing to bet substantial sums of money that "eventually" will not include either of our lifetimes.

I'm not so sure, but no one can predict the future. :) I wouldn't have thought Rust would end up in the Linux kernel when I first heard of it. Now it's all but certain to happen.

> And my guess is it would be far less work to port C to (or write an LLVM backend for) x86-128 or aarch256 or RISC IX than to maintain your own language and keep it running on all the major platforms. But good luck to you nonetheless.

That's true. It's why my language will bootstrap itself to C99! For every platform that is too much work to support directly, I'll support it by having a C99 compiler for that platform.

C99 should not need much maintenance. I hope. Or someone else will care enough to do it. I hope.

> I'm pleased you pointed this out! I'd debated saying this but opted not to, it's great that we agree on that extra detail.

Good! And you're welcome.

Yeah, I'm picky. I've rewritten code given to me by a FreeBSD kernel developer who is twice my age and much better than me.

> If we expand that to Reddit and Hacker News, I have to agree, so it might have just been personas I went up against.

"Twitter personas" is just my pet name for the phenomenon because it seems strongest (or maybe I just first noticed it) there.

> But I've never been to RustConf, so I can't dispute this. I'll simply have to trust you on this one.

Hah! I've never actually been either. I just meant this as a standin for putting you in front of actual, real, physical people who also are likely closer to the evangelist end of the spectrum.

Lest you lump me in with the RESF, I just want to make it clear that all I did was point out your overconfidence in your C abilities. I don't care what language you use or anyone uses. I think Rust has lots of problems that it's stuck with, and I've said on multiple other occasions that the ideal language would be a mix of Rust (borrow checker, typesystem) and Zig (comptime, generics, explicit allocation).
Gavin, there is no point in arguing with fanatics. (You have to know that none of them are actually going to dive into your code and possibly learn something new that didn't come from a vetted authority figure). They are incapable of listening to their own independent thoughts, assuming that they have them, and must attack anyone who counters their dogma because it risks shattering their core beliefs, which is intolerable. The funny thing is that the truth of rust is right there in its name. It is a corrosive process that ruins the iron that it touches.
I really like C. I did actually spend about an hour reading his code. It's very nice, and I genuinely believe that Gavin is probably capable of writing memory-safe C most of the time. Except when his sanitizer setup is accidentally disabled, of course.

I did find at least one case where a function in isolation is explicitly not memory-safe, but its safety depends on implicit and undocumented assumptions about how it's called. I didn't find a way to exploit it from the userland program. In `bc_parse_addNum`[1], a `char *` string is indexed into without checking the length. Callers are expected to provide strings of at least length 2. That expectation is not documented, though it is adhered to. But it is a landmine waiting to be tripped over should that assumption change.

But this is a sideshow. Experts have been insisting for decades that they can write crash-free C and yet we continue to regularly find exploitable memory issues in every large multi-author C project. It's plain as day that—for almost all of us—an increasingly indefensible amount of the time spent on C programs is in dealing with the types of bugs that languages like Rust prevent outright. Whether that's simply finding and fixing them, architecting programs to avoid them, incorporating those fixes into downstream projects, mitigating their impact in live production systems, or whatever, our industry pays an enormous ongoing cost. Even in projects that have never had a public release with a memory bug, significant engineering time is spent on them just during development iteration.

As a handy example, the Linux kernel is still trying to rid itself of `strlcpy`[2] which has been the source of multiple CVEs. This process has taken upwards of twenty years. And that's after spending god knows how much time and effort migrating to `strlcpy` from `strcpy` in the first place.

[1] https://git.yzena.com/gavin/bc/src/branch/master/src/parse.c...

[2] https://lwn.net/Articles/905777/

> I really like C. I did actually spend about an hour reading his code. It's very nice, and I genuinely believe that Gavin is probably capable of writing memory-safe C most of the time.

This is a nice compliment, thank you.

> Except when his sanitizer setup is accidentally disabled, of course.

Fair criticism. XD

> I did find at least one case where a function in isolation is explicitly not memory-safe, but its safety depends on implicit and undocumented assumptions about how it's called. I didn't find a way to exploit it from the userland program. In `bc_parse_addNum`[1], a `char` pointer string is indexed into without checking the length. Callers are expected to provide strings of at least length 2. That expectation is not documented, though it is adhered to. But it is a landmine waiting to be tripped over should that assumption change.

Callers are actually required to pass a string of length 1 including the nul terminator, but you are correct, this assumption is not documented in `bc_parse_addNum()`, and it should be.

By the way, `bc_parse_zero` and bc_parse_one` are constants, so I can make assumptions about them. This is why an empty string is fine: those constants do not have nul terminators at index 0, so if the string parameter does, the short-circuit operators will short-circuit.

I've pushed commit e4b31620f181 to document that assumption, along with a note that assuming a non-empty string might be useful too.

> But this is a sideshow. Experts have been insisting for decades that they can write crash-free C and yet we continue to regularly find exploitable memory issues in every large multi-author C project. It's plain as day that—for almost all of us—an increasingly indefensible amount of the time spent on C programs is in dealing with the types of bugs that languages like Rust prevent outright. Whether that's simply finding and fixing them, architecting programs to avoid them, incorporating those fixes into downstream projects, mitigating their impact in live production systems, or whatever, our industry pays an enormous ongoing cost. Even in projects that have never had a public release with a memory bug, significant engineering time is spent on them just during development iteration.

I agree with this. I never said people should use C by default; absolutely not. They should use Rust by default.

But as I said in another of my comments [1], I think I personally would write buggier code in Rust than in C.

[1]: https://news.ycombinator.com/item?id=32915468

> I've pushed commit e4b31620f181 to document that assumption, along with a note that assuming a non-empty string might be useful too.

Nice!

> By the way, `bc_parse_zero` and bc_parse_one` are constants, so I can make assumptions about them. This is why an empty string is fine: those constants do not have nul terminators at index 0, so if the string parameter does, the short-circuit operators will short-circuit.

Ah, of course. I knew that they were constants, but I didn't consider the short-circuiting of the comparison before indexing further into the string.

> But as I said in another of my comments [1], I think I personally would write buggier code in Rust than in C.

I hope you understand that—all snark aside—I truly, genuinely believe you. I do suspect that if you had invested the just time you've spent figuring out how to work around C's memory-safety shortcomings, your proficiency would be within spitting distance. But obviously those costs are already sunk. And at the end of the day, if you just love C and only want to write C then it doesn't matter what sorts of things another language provides.

I love C, but I've also come to love Rust. Sum types and exhaustive pattern matching are the sorts of things that are hard to live without once you've had them, and now languages that don't offer them are pretty much ruined for me. But at the same time I'm not a fan of the async/await paradigm, though I begrudgingly understand why it was necessary and why it was designed the way it was. For now I simply avoid it, but it makes me sad that we were never able to find something better.

> Ah, of course. I knew that they were constants, but I didn't consider the short-circuiting of the comparison before indexing further into the string.

No worries! That's why I specifically wrote it that way instead of a `strcmp()` call. I may be a little obsessive over getting my code right.

> I hope you understand that—all snark aside—I truly, genuinely believe you.

Thank you.

> I do suspect that if you had invested the just time you've spent figuring out how to work around C's memory-safety shortcomings, your proficiency would be within spitting distance. But obviously those costs are already sunk.

I actually don't know. It's possible, even plausible, that you are correct.

But I've spent gobs of time trying to understand async/await and failed. It wasn't as much time as I spent honing my C, but it was a lot. And I did not seem to make progress.

However, I might have been making progress and didn't realize it. Or maybe an epiphany like the one I experienced with Haskell would have been in the future.

Or maybe my brain just doesn't work in a compatible way with async models. I don't know.

It is one of my regrets that I did not try harder. Oh well; I guess I loved the visible progress of fewer and fewer crashes in a fuzzer more, even if it was slower.

> And at the end of the day, if you just love C and only want to write C then it doesn't matter what sorts of things another language provides.

As long as I am not negligent! I'll add more about this in a reply to another of your comments, though.

> I love C, but I've also come to love Rust. Sum types and exhaustive pattern matching are the sorts of things that are hard to live without once you've had them, and now languages that don't offer them are pretty much ruined for me.

I agree. I love them too, so much so that I run clang with -Weverything to get exhaustive matching in switch statements. And I emulate sum types with enums and unions. I always use switch statements to match on the enum value, which sort of gives me the experience of Rust sum types and exhaustive pattern matching. Sort of.

My language will have them for sure.

> But at the same time I'm not a fan of the async/await paradigm, though I begrudgingly understand why it was necessary and why it was designed the way it was. For now I simply avoid it, but it makes me sad that we were never able to find something better.

I agree. I'm sad about it too. I couldn't really reject Rust if it didn't have async/await, and I wish I didn't have to reject Rust.

(Though the RESF is still off-putting.)

I'm hoping that my language will be a competitor to Rust but allow people to try structured concurrency instead. If Rust still "wins," that's fine; people want async/await. But if they coexist or my language "wins," that's good too.

Eh, sorry for the long-winded comments.

> But I've spent gobs of time trying to understand async/await and failed. It wasn't as much time as I spent honing my C, but it was a lot. And I did not seem to make progress.

I've said this elsewhere but as a long-time Rust user I have literally never used or even encountered async/await. It exists, and I could use it if I needed to, but I never have nor have I had to spend effort avoiding it or thinking about it. It as far as I can tell a feature you can essentially entirely forget exists.

I'm glad you said this because my impression of Rust async/await until now was that it was unavoidable, mostly because I heard that all of the big-name crates, the ones you would use in just about every project, use async/await.
I think you hear about them more because there’s been a lot of pent up demand for async and people who’ve been waiting for it are excited. But I can count on zero hands the number of times I’ve wanted to use a crate but the only one available required async.
Big-name crates that do IO often use async by default, but I haven't seen one so far that doesn't provide a sync/blocking api as well. Usually this is done by enabling a feature for the crate.
I am also wondering about your confidence given the fact that there are obviously memory bugs during development... what gives you so much confidence that no memory bugs exist in released versions? Do you have an extensive test suite with valgrind /etc to ensure that there aren't any memory bugs before a release but some can slip in in intermediate versions? Or what do you do that gives you the confidence to say that there aren't any memory bugs in the released versions? Or what is involved in all the extra effort it takes to make a memory bug free c program?
You misunderstood what I mean by "gap" here. The gap isn't that it is impossible to produce security/reliability equivalent program using C vs Rust, which you seem to be arguing. The gap is that statistically for many code written in real world for various degree of efforts, Rust code will have much less of security/reliability issues, and it will take much less effort to get to the similar quality point compared to C or C++, and that gap is NOT bridgeable by making C programmer better or by inventing better conventions and styles.
Mission critical is almost meaningless when applied to the entire software industry. It’s whatever each company wrote their core software in. For twitter Ruby was mission critical, for Facebook it was PHP.

Security critical is also rather meaningless, because the idea that a specific language must be used to write secure software is something that the Rust community is claiming but is otherwise unproven and not particularly popular as an opinion. In fact I’ve seen many counters that nearly any GC language offers the same security guarantees as Rust.

Finally, there’s the mighty inconvenient fact that a large amount of safety-critical software (a well-defined term and domain!) is written in C and C++ with a track record of multiple decades while Rust is completely unproven.

> Finally, there’s the mighty inconvenient fact that a large amount of safety-critical software (a well-defined term and domain!) is written in C and C++ with a track record of multiple decades

Well stated.

No one's talking about your personal project here. The audience is teams of people building software to be used in production.
Except that the tweet was pretty absolute. He could have had a reply tweet with something like "unless you have to or you're doing a hobby project." I took issue with the absolutism.
Those qualifications are going to hold for any advice about technology.

You can even justify using malbolge for your hobby project with "I like it" or "It's just for fun".

If your company is only going to pay you for producing malbolge code, then you write malbolge or quit. If you decide to stay, then trying to change their mind might be a good idea if you can spare the effort.

> Those qualifications are going to hold for any advice about technology.

They should hold, but the RESF can be too absolutist. The wording of the tweet encouraged that, so I was just trying to push back on it.

Gavin's personal project is being used in production.
> Oh, and it's possible to make C as good as Rust: I've got macros to do automatic bounds checking.

The really tricky macro though comes when you want to check races in shared mutable state...

No macros. This is one spot where Rust is better than C. (Though it is too limiting for my taste.)

Instead, I use ThreadSanitizer and add locks where I may not even need them. Then I may remove some, or change them to different synchronization primitives, and between every change, run TSan several hundred of thousands of times to tease out any race conditions. It's my way of fuzzing for race conditions.