Hacker News new | past | comments | ask | show | jobs | submit login
Will Carbon Replace C++? (semaphoreci.com)
130 points by redbell on Feb 27, 2023 | hide | past | favorite | 321 comments



The article is about creating a potential successor to C++ in the same way JavaScript lead to TypeScript, or Java lead to Kotlin, or C lead to C++, and in giving those examples immediately undermining its own thought because none of those replaced the thing they came out of. Heck looking at whose still writing new code bases in what, C++ didn't even replace C, and Swift didn't replace Objective C. C++ and Switft just became "more dominant".

So based on the article's own observation: no, of course not. The more interesting question is "will it stand on its own?" to which the answer is "only if it actually solves so many problems with the thing it's trying to supplant that it makes sense to give it a serious try".

And C++ just... doesn't have that many real problems. It has a lot of irks, but the problems people run into are problems that others already solved, a thousand times, over the last half century, in many different ways for many different iterations of the language.

Pretending you can replace C++ is like pretending you can replace cars. Not just "create EVs" but straight up replace cars. Good luck, you won't succeed if that's your goal, so hopefully you realise you need to focus on making a decent language that some folks might consider using instead of C++ for some of their work, instead of creating "the successor to C++".


> And C++ just... doesn't have that many real problems.

It does not have many, but it has one and it's big. It's not memory safe.

Check out this talk by Herb Sutter, around minute 43:

  This is the first time a government [see note] has actually issued guidance to industry broadly that was the barest paraphrase away from "where possible don't use C and C++"
[ Note: in this context, the "government" is the US Department of Commerce and NIST, which, according to Herb, have issued a detailed guidance in response to the Executive Order on Cybersecurity [2]. While I couldn't find that guidance, I found one by the NSA [3], which saw quite a few comments here on HN in December last year [4] ].

[1] https://www.youtube.com/watch?v=ELeZAKCN4tY

[2] https://www.whitehouse.gov/briefing-room/presidential-action...

[3] https://media.defense.gov/2022/Nov/10/2003112742/-1/-1/0/CSI...

[4] https://news.ycombinator.com/item?id=33560227


> It's not memory safe

Modern C++ has made big inroads into removing memory safety issues though. Memory safety bugs are relatively uncommon in modern C++ compared to pre C++11 times.

You could argue that C++ is still "unsafe by default" and you'd be right. But most C++ programmers use smart pointers and unique pointers rather than raw pointers now, vectors instead of raw arrays, etc.. And it does make a big difference.


It's not that people can't deal with pointers. The most common issue in C++ is how many ways to shoot yourself in the foot with common utils. Like, we use a lot of abseil utils at work that return string_views instead of new strings, and if you're directly passing that somewhere else, you easily corrupt your memory.

std::string foo = "foo";

const std::string foo2 = absl::StripAsciiWhitespace(absl::AsciiStrToUpper(foo)); // in Python: foo2 = foo.upper().strip()

std::cout << foo2; // garbage

Yeah, all technically the user's fault, but it gets pretty tiring worrying about this stuff when you're writing a high-level application and the few CPU cycles you save don't really matter. No matter how good you are, you will make mistakes, and the chance of one bug corrupting memory in your whole process increases exponentially with the LoC written. Also I have to point out the irony in a language being type-safe but not memory-safe.

Also, I didn't expect Java-looking class syntax to leave member variables uninitialized (garbage) if you don't set a default. That should at least be a compiler warning, I mean how often do you actually want that?


    <source>: In function 'int main()':
    <source>:6:54: error: conversion from 'absl::string_view' {aka 'std::basic_string_view<char>'} to non-scalar type 'const std::string' {aka 'const std::__cxx11::basic_string<char>'} requested
        6 |   const std::string foo2 = absl::StripAsciiWhitespace(absl::AsciiStrToUpper(foo)); // in Python: foo2 = foo.upper().strip()
          |                            ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ASM generation compiler returned: 1
This is gcc with c++20, curious what the garbage is you're describing.


Oh sorry, foo2 should be auto in this example (which becomes string_view). StripAsciiWhitespace takes a string_view here: https://github.com/abseil/abseil-cpp/blob/master/absl/string...

The garbage comes from AsciiStrToUpper returning a new std::string which StripAsciiWhitespace takes as a string_view (implicit conversion). By the time you print foo2, the string is already freed.


This is a classic misuse of rvalues so I’m not sure it’s a huge problem. I don’t think it’s a problem with C++. I probably work at the same place you do btw and I am pretty sure there are rules/guides about how to handle string_view lifetimes

For those downvoting, please explain why you think string_view should take ownership of an rvalue string


All this talk of rvalues, auto, and string_view is PRECICELY the problem with cpp.

There are so many details you need to keep track of, and eventually you make a mistake. Now, yes, i know what all of that does, and how they are supposed to be used, but it does not remove the cognitive load.

Many languages have a substantially lower cognitive load when doing something trivial, such as ToLower().ToUpper(), etc.


Every systems-level language will have these sharp edges handled differently. Have you heard of borrow checkers? Many languages don’t have to concern programmers with rvalues or equivalents at all because they are garbage collected - should everything be garbage collected?

Let’s not make this a language war, there has to be some programming language that does low-level memory operations without batteries included for some types of technologies. When I write code in C++ and I want something like garbage collection or ref counting I can reach for a shared_ptr.

If you don’t want to concern yourself with types, values vs references, or manual memory management don’t choose C++. The default handling is sane if not necessarily intuitive. You shouldn’t create a ref or pseudo-ref (string_view) to data that is not on the heap and no longer allocated to the stack - seems sane. This problem could be easily caught by breaking function calls into separate lines and explicitly specifying the types at each step.


> Every systems-level language ...

Is Cpp systems-level language? As I see, the problems arrives from the fact that Cpp is a multi-paradigm language, and as such contains a near endless wealth of features to combine. Also modern Cpp takes a clear direction away from low level to (relatively) more high-level language. The problem really comes from the combination of low level and high level paradigms in the same language/codebase, where the expectations of the behavior of each piece of code can vary wildly.

> ... will have these sharp edges handled differently

Perversely, plain C, often has a lower cognitive load than Cpp. This is because you must always manually handle pointers, types, object lifetimes, etc. Now, this does result in a high cognitive load, BUT, the cases as in Cpp where you might combine auto, with a temporary, with a pointer inside, referring to some unseen resource, cannot happen, because you cant do that in C. So the worst case in cognitive load is never as bad as in Cpp. The lack of features means less possible combinations to shoot yourself in the foot. (Though C does still have many, nor is C an ideal language)

> Let’s not make this a language war

Discussing the problems of Cpp is not language war. Nor is understanding the merits and problems of the Design of Cpp.

> If you don’t want to concern yourself with types, values vs references, or manual memory management don’t choose C++

But IF YOU DO write Cpp, there is no escaping them. Which is my point.


Many languages don’t have to concern programmers with rvalues or equivalents at all because they are garbage collected - should everything be garbage collected?

From Xerox point of view, yes. Unfortunely they lost to the UNIX workstation market.

Interlisp-D, Smalltalk and Mesa/Cedar.


There might be a reason they lost.

Believing that one size fits all is a sure way to alienate a lot of people who don't fit that size. Right tool for the right job and giving the freedom for people to solve their problems in the best way is a better way to win people over.


Free beer UNIX on cheaper hardware, plus bad management, basically.

Nothing to do with the technology.

Hence why I love why Android is so locked down to native code, and Apple is doubling down on Swift.


Yeah, you shouldn't have GC in systems-level code any more than I should have lifetime concerns in application-level code. Problem is leaders end up choosing C++ for both and saying y'all should know how to deal with it.

Google also has a lot of stuff in the middle where they're fine with sacrificing a little speed for a lot more safety, but Java etc are too slow. Golang was supposed to satisfy that, but I'm guessing it was too big of a leap from C++.


It's good that you can solve this with 100% of the team following 100% of the time the rules/guides.

It's even better if your language has a way to express "the return value points to data from the input argument, so it's a compile error to pass a rvalue string to this function". The second we got a language able to do that, usable everywhere where C++ is, (yes, that one) the incapacity of C++ to express this became "a problem with C++". Our expectations have just increased.

Surely it can be catched via static analysis if you suppose the common case that the return value is a function of the argument, and not pointing to some static global data. But you will get false positives when somebody does the uncommon case. There is a lack of expressiveness in C++ here.


The "oh shit" moment when we found that our database's indexes got mysteriously corrupted and we had no idea from where. What do we do, fire the entire team to get rid of whoever made the bug?


But C++ can express that, with compiler extensions:

https://godbolt.org/z/ohxaGzsEM


That's cool.

Last I remember, the lifetime profile stuff was there, but there was still no way to add your own annotations. For some reason, I didn't hear too much about any of this, it was

- clang is working on it

- clang is working on it

- clang is working on it

- Visual Studio has it

- clang is working on it

- Silence

gcc still has nothing, right?


I have just taken a look... https://wg21.link/p1179 is actually still not there, right? I see some interesting stuff in https://discourse.llvm.org/t/rfc-lifetime-annotations-for-c/... from last year. But, in general... once Herb started the whole Lifetime safety profile thing, there seemed to be a lot of interest, but for the last few years things seems to have died? I think things are better with Visual Studio, but being on Linux... I may need to start developing for Linux from Visual Studio with WSL2 :-(


Only VC++ is working on it, the clang tidy developer looking into lifetime has moved on.


That's just sad.


When you're writing a ton of web backend code dealing with strings all over the place, it's easy to forget to check whether something is accepting and returning a string or string_view. `auto foo2 = StripAsciiWhitespace(AsciiStrToUpper(foo))` doesn't say what's going on.

I didn't downvote, btw. I don't do that in general.


Heh this is normally why I tell my new teammates to be careful about using auto in non-test code outside of well established patterns like iteration. Auto will bite everybody in the butt at some point!


We don't got time for non-auto. Better yet, we should've just written all our stuff in Python or Java. We have no legitimate need (performance etc) for C++, Rust, or even Golang.

Even if you use string_view on the LHS instead of auto, pretty easy to miss the bug here.


Same here. I avoid auto in my code except iterations. Just a mental pattern. I understand that people coming from "typeless" languages might not like it at all, but it is like with guns. You can play with water pistol but you do not play with real guns, you follow some rules if you want it safe. Modern C++ in my opinion supplies enough features and tooling to help with making reasonably sure the rules are followed.


auto is the least of your worries when it comes to memory safety in C++.


Classic C++


And yet "Almost Always Auto" is "Modern C++"...


Citation needed? My team generally avoids auto and tends to spell out the types most of the time, which we find makes everything more readable. Code is written once but read many times...


A citation of what's "Modern C++"? The term is a made up concept with no proper definition...

But "Herb Sutter says you should use it, he even gave it a catchy name/acronym" is as good as it gets. And he does so AFAIK in the same place he created the "Almost Always Auto" name: https://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style...

Notice that he says "the main reasons to declare variables using auto are for correctness, performance, maintainability, and robustness—and, yes, convenience, but that’s in last place on the list.". He is arguing literally the opposite of what you do, that using auto avoids bugs ("for correctness").

I'm not going to argue in favour or against "Almost Always Auto". But I see no problem calling it "Modern C++".

* Herb Sutter being the convener of ISO WG21


imo types don't make things more readable. You know the "fluent programming" thing where you do obj.doThis().doThat().doThis().doAnotherThing() and probably 20 more lines of this? That's entirely because people didn't want to bother writing out LHS types, but whatever version of the language only let you avoid that if you chained things (there was no auto or var). Maybe it's more of a Java practice, though.


Your local style guide can’t override this?

Just turn people loose on your codebase without supervision and be really surprised that the hackers make off with your data?

You, sir, are arguing from bad faith as your obvious mission is to promote “rust in all the places”.


Our style guide says "almost never auto," but most people auto everything. They can make the linter replace auto with the actual type if it's really that big a deal. Explicit type wouldn't have avoided this bug.


Arguably an explicit type would have made the bug a little bit more obvious. You basically expect, by default, this kind of string manipulation functions to return a std::string. Obviously in this specific case you can return a view, and that makes it more performant; but it's kind of unexpected and using auto leaves the surprise a bit more hidden.

But sure, you can still make the error with expiclit types.


I agree, the string_view on the LHS might make you think more about the lifetime, but I'm pretty sure we all would've missed it.


Not to detract from your general point, but are you sure your example corrupts memory? AsciiStrToUpper returns a std::string (it has to), which in your example becomes a temporary object. Temporaries are destructed at the end of the containing full-expression, which in this case is the whole assignment expression. So StripAsciiWhitespace returns a view into a still-living temporary, and foo2's constructor allocates memory and makes a copy. Only then is the temporary deallocated.

Now, if you wrote absl::string_view foo2 = etc., you'd have a dangling view for sure. In practical industrial usage, you'd build with an address sanitizer (it's built into clang: -fsanitize=address), which should catch that issue.


I missed one important little piece in my example, should be `auto foo2` (to make it more of a landmine) or `string_view foo2` and not `string foo2`, as you've noticed. There's an overloaded func taking string_view and returning string_view.

We use an address sanitizer in tests but not in production. IIRC we had one untested log output line like this that caused corruption in prod.


> Also I have to point out the irony in a language being type-safe but not memory-safe.

Misnomer aside, there is no contradiction. Type safety is much easier to reason about at compile time than memory management. So, it shouldn't come as a surprise. You need a rust like "borrow checker"-by-default functionality.


It's not surprising that they use static types in C++, but it's not about safety. It's about knowing the size of everything at compile time. Dynamic typing requires moving more towards the "interpreted" side of languages and incurring the performance cost of that.

The contradiction is when the veteran SWEs I work with say we use C++ instead of Python for the added safety of compile-time type checks, treating dynamic typing like a bigger risk than memory trampling (never mind that Python has type-checking too if you really want it).


For very large projects static types in C++ are a lot safer than Python. For simple projects I agree with you, but as you get over 50k loc Python becomes hard to manage, while i'm work in 10 million lines of C++. Sure it takes more effort, but at that size C++ is a lot easier to manage.

C++ does have issues. However few languages can handle complex problems well. (Rust is very intriguing for the possible ability to do things at the same scale)


10 million C++ lines is 10 million chances for you to misuse memory and cause your entire program to behave unpredictably, from simply crashing to writing garbage directly into your database. Imagine you're on a team of 8 and find one day that your DB's indexes were mysteriously corrupted, what do you do next? It's happened here.

If you use the wrong type in Python, you get an unhandled exception failing to find a property or something, that's about it. Maybe there's a contrived scenario where it'll succeed in a wrong way, but again that's a smaller blast radius


The likelyhood of Python crashing is a lot higher as it is much harder to know you didn't break your error handling path someplace that isn't tested. C++ sometimes has memory issues, but not nearly as often as Python has problems in the error paths.


Python is exception-based, so it's easy to avoid a crash. Say it's a webserver, you catch all exceptions around each endpoint and give HTTP 500 if it's not something you understand to be a 4xx. Exceptions are nice in that you either explicitly handle them or the caller will.

C++ has exceptions too, but I've never used them, so idk. The abseil statuses end up being used like DIY exception handling, and it's ok but a bit easier to mishandle something than in Python. And a segfault cannot(? or shouldn't) be caught and will crash the whole program.


I am not writing a web app, I'm writing an embedded system. Catching an exception is nice, but I still need my code to keep working, which memory leaks do allow, generally for a long time. yes we have had some 'memory scribbler' bugs that were a pain to track down, but they are very rare compared to changing python code and missing to make the right change to an error handling path and now Python unwinds to main instead of handling the error correctly. Note that I'm saying Python errors of that nature are more common despite comparing 50k Lines of Python to 15m lines of C++.

For short programs Python works great, but it doesn't scale to large programs.


You can comfortably write a large web app in Python or similarly in JS, and people do. For embedded, it's already out of the question for other reasons. And you probably don't want exception-based handling in embedded, yeah.


> Yeah, all technically the user's fault,

The problem is C++'s priorities. Priority #1 is performance, and if you look closely, nearly every single instance of this buggy-program hostile attitude comes down to the language and libraries absolutely refusing to do any kind of dynamic safety checking by default. UB can be traced directly from "it's too hard to reason about the implications of buggy programs" to "well, don't do that, stupid programmer".


There's a talk by Scott Meyers (at the D lang conference IIRC), where he methodologically takes apart the claim that priority #1 is performance or 0-cost abstractions. Basically the way the standards body seems to work is there's ~N different concerns and people will whatever set is appropriate to kill proposals. It gives a fantastic illusion of performance being #1, but C++ makes plenty of choices that are misaligned with performance (e.g. variable aliasing that it inherited from C but it let infect the C++ type system too).


There are tradeoffs. If performance were always #1 with the underlying requirement of portability, you'd be using C. And performance is more of a concern in C++ than in Java.

I'm no expert in this, I'm just a guy who's sick of writing web backends in C++ for no reason.


You'd think so, but C doesn't have the performance crown always either due to language design choices. A big one is aliasing (which languages like Rust and Fortran forbid) which inhibits the ability for very impactful and common low-level optimizations that come up all the time. Performance characteristic differences between C vs C++ are not all that interesting because the language models are so similar (& thus similarly the compilers for them basically have the same model). Indeed, higher level of abstractions can help improve performance as virtual classes will outperform manual attempts at doing similar things (due to devirtualization passes within the compiler). That's actually been a friction point for Rust using LLVM because LLVM is built around the C/C++ language model and it's hard to express certain invariants to it that would result in even more efficient code or you try to use optimization passes that turn out to be broken because they're not really used by the broader C/C++ community (https://github.com/rust-lang/rust/issues/54878).


Ah the days of ISAPI ATL extensions. :)


As far as I can tell, Priority #1 is backwards compatibility. For example, std::regex can be slower than launching PHP and running the regex there¹, but that won't be fixed because it would require an ABI break. I'm not sure how that happened, as neither the poor performance nor the unwillingness to change ABI were unknown. Performance seems to not have been the top priority in the design of std::unordered_map either, which requires reference stability and therefore boxing. This got added in 2011, 18 years after the birth of the stl.

¹: https://cor3ntin.github.io/posts/abi/


> Priority #1 is performance, ..

No. It's not. It's designed by committee -- impossible to deprecate old misfeatures, trying to entertain everybody but please nobody.


Deprecating old features is not reasonable for a widely used language. Just look at what happened with Python 3.


Yep. If I upgrade my version and just a basic `print` no longer works the same, I go back.


Plenty of people are pleased with it. It gets the job done, if you're using it for the right job.


You can implement your own libraries that do this easily. The std libraries have to maintain backwards compatibility and typically solve the base case only - just wrap them to do whatever ref counting or bounds checking you want


This is simply false, modern C++ just replaces old issues with new ones. There are numerous new unsafe footguns that "modern" C++ introduced with lambda captures, coroutine lifetimes, and libraries like std::range where lifetimes and ownership are incredibly difficult to reason about. Not to mention that the web is full of blog posts about how to properly use std::string_view, since a lot of crashes trace back to improper use of it, particularly its constructor that kind of acts like it takes ownership but doesn't.


> Modern C++ has made big inroads into removing memory safety issues though

Modern C++ adds new features that allows you to write code that doesn't have as many memory safety problems, but all the unsafety (is that a word?) that existed in the past still exists.

Removing features that allows memory unsafety will probably never happen, because one of the main reasons people use C++ is all the legacy code will still be used for decades.

It's great that you can write C++ using only the newest features, and that does increase safety. But that doesn't offer the same guarantees of languages designed to simply not have these kinds of problems, or that by design flag the points in the code where safety can't be guaranteed by the compiler.


C++ has so many features that it looks like a different language, depending on who's writing it. It can still compile decades-old code written to the oldest standard, or brand-new code with the latest memory safety features.

So is there a compiler flag or external linting tool that can generate warning messages when you're using an older memory-unsafe technique where a safer and more modern technique could replace it?


You can write completely memory-safe code using nothing but C++98 features, like templated smart pointers and whatnot, which wrap around the unsafe parts of your code. You can keep that unsafe part small and get it right "by inspection"; then if it's used through the higher level primitives, it cannot be misused.


The problem is that there's no way to automatically check any of that.

If the code is small and doesn't change or doesn't have to last for too long, that's OK. But when it's changed over the years, it's pretty much impossible to guarantee that the unsafe parts are kept small and contained, especially as programmers leave and new ones come in.


Aren't vectors just as vulnerable to out-of-bounds access as any C-like array? Most C++ additions have plenty of undefined behaviour.


Not if you stick with the ::at() method, which does bounds checking

https://en.cppreference.com/w/cpp/container/vector/at


Unfortunately, std::span doesn't have at().

Note that std::vector's at() predates C++11, whereas std::span was added in C++20. It's a myth that C++ is getting more memory-safe; in many aspects it's actually regressing.


Regardless of all that, you can make your own vector class which works exactly how you want and is completely safe.

In a greenfield project where you control every line of C++ code, you can easily achieve very good safety using nothing but ancient C++ features.

Not just memory safety. I mean, you can make your own numeric types that do overflow checks and throw exceptions or whatever. It probably won't be very fast, but it will be solid.

People have used C++ (ancient C++) to make numeric types with units, where you can't add "kilograms per second" to "meters". I remember that from some talk thing I went to in 1999.


std::span doesn't have at() because std::logic_error was a mistake. Using std::vector's at() is a mistake (you could use it as a helper method and make it as if it throwed std::runtime_error, but it doesn't, that wasn't its intended usage).

All three major C++ standard library implementations have an option to enable assertion checks in both std::vector and std::span operator[]. Enable them unless you are in such a resource limited environment that you can't afford the checks (unlikely). The only reason the standard doesn't require the checks is to allow C++ to be usable in those resource limited environments. You could argue the checks should be enabled by default, but that's not something for the standard to decide, complain to your standard library vendor.


It's not just the indexing you have to worry about, though. It's also out-of-bounds iterators. And while, yes, you can tell your implementation to emit checks for those as well, it's so slow in practice that nobody uses it in optimized release builds (and some implementations don't even support such use).


Sure. I agree. I was just arguing that it's good span doesn't have at(), I was not trying to say C++ is memory safe.


> Modern C++ has made big inroads into removing memory safety issues though. Memory safety bugs are relatively uncommon in modern C++ compared to pre C++11 times.

I remember when people said the same thing about C++03. Plus ca change.


It was true, which makes it silly to be saying it about C++11, C++14, C++17, ...

In C++98 you could develop a program with some unsafe core of whatever resource management you wanted, and then wrap it with the right classes so that it can't be misused.

After circa 1995, anyone struggling memory safety issues in greenfield C++ code that was completely under their control (no legacy) had to be a supreme goofball not to be leveraging the language to make that sort of thing go away.


And yet we keep seeing memory safety issues in C++ code even when that code was written greenfield long after 1995. (E.g. IIRC cloudflare's cloudbleed was in a codebase that had been started in about 2012).


Looking at this, that is not clear. The report below (courtesy of Wayback Machine) mentions some external HTML libraries, as well as the development of modules that plug into NGINX, and work on raw memory buffers (I'm guessing, dictated by NGINX). Hard to speculate without seeing the code. Not that it's an excuse; greenfield C++ code could find ways to interface in a bullet-proof way with something or anything that communicates using low-level buffers.

The "Ragel" tool they used evidently generates C that uses raw pointers:

> The Ragel code is converted into generated C code which is then compiled. The C code uses, in the classic C manner, pointers to the HTML document being parsed, and Ragel itself gives the user a lot of control of the movement of those pointers. The underlying bug occurs because of a pointer error.

The bug in these Ragel-generated parsers was somehow hidden or compensated for by some buffering strategy, which they tweaked when introducing some new kinds of parsers "cf-html". Those didn't have the bug, but the different buffering turned on for them exposed the bugs in the Ragel based parsing.

https://web.archive.org/web/20170223233000/https://blog.clou...

I'm looking at the Ragel State Machine Compiler user guide. Chapter 5 (Interface to Host Program) makes it quite clear what sort of thing the Cloudfare people chose to grapple with. Ragel will write code for you planted into middle of any C function anywhere; you must provide numerous predefined variables, under prescribed names, some of which are pointers to data, and so it goes. For some languages, there are safer interfaces: for Java and Ruby there is a buffer and instead of a pointer there is an index into it. Ragel could have been upgraded to have actual C++ support of some kind.


Because what helped C++'s adoption, copy-paste compatibility with C, is also its acquiles heel, no matter how much the security gets improved.

Cloudbleed was found out in C code, with the usual issues dealing with bounds in C.


If C++ adopted a way to namespace safe or unsafe code (unsafe by default would keep retro-compatibility) and had the tooling needed to catch memory safety bugs at compile time, that would be enough for me.

The effort needed on tooling would be significant though. I don't see that happening and overtaking Rust.

(btw the correct spelling is Achilles, Achilleus, Akhilleus, Ἀχιλλεύς)


GNU and Clang toolchains have useful diagnostic abilities in this direction, though no single "master switch".

For example, with -Wold-style-casts you can diganose every use of the (TYPE) EXPR casting notation, which is often seen in the lower-level C-like C++ code for punning memory.

Somewhere in some commonly included header for the project you can write declarations for C functions that should not be used, marking them deprecated. Then if people introduce strcpy or malloc or whatever you don't want, that can be diagnosed (and can fail compilation, if desired).


I feel the same, despite its warts I still like coding in C++.

VC++ has some annotations on that sense, problems are two fold, get the vendors to agree, and the C subculture that security actually matters.

Thanks for the correction.


Most programmers sadly keep using C idioms even while writting "modern" C++, just look at recent samples provided by companies with seat at the ISO table, some of which have even provided famous security reports.


> > And C++ just... doesn't have that many real problems.

> It does not have many, but it has one and it's big. It's not memory safe.

It's not as big as a deal as c++ opponents make it out to be. The ratio of memory bugs to other bugs at work is basically zero. The problems that are holding our product back have nothing to do with memory safety. Of the long list of problems we need to solve, that just isn't one of them. If the only thing a new language offered over c++ was that I don't have to think about that 0.01% of bugs anymore, but in exchange I get either a garbage collector or a borrow checker to fight with, I would not switch.


>"It does not have many, but it has one and it's big. It's not memory safe."

Enough of this already. Not going to discuss ancient code. I currently using modern C++ and it has enough features to keep one's code reasonable safe if that was the goal. And frankly I do not remember any reported bugs in my production caused by "memory unsafety". Just plain old logic errors every once in a while.


> It's not memory safe.

The computer isn't "memory safe." If you want a language that can express every function of the hardware it runs on, you expose this fact as well.

Careful management of "unsafe" blocks might be an answer, but I suspect we're going to have to dig way deeper until we find a truly "safe" solution. At that point, would it actually matter which language you use?


“There’s going to be some bugs no matter what we do. So why try substantially reducing 70% of the bugs we see?”

https://www.chromium.org/Home/chromium-security/memory-safet...

https://msrc.microsoft.com/blog/2019/07/a-proactive-approach...


I'm saying fix them. I'm also saying, I don't think the language is the appropriate level to do this at.

You can see the clear conflict in the mentality of these new languages. "Fast and, somehow, safe!" It's missing the forest for the trees, much like your retort.


> Fix them.

People are. Like on Android.

> In Android 13, about 21% of all new native code (C/C++/Rust) is in Rust. There are approximately 1.5 million total lines of Rust code in AOSP across new functionality and components such as Keystore2, the new Ultra-wideband (UWB) stack, DNS-over-HTTP3, Android’s Virtualization framework (AVF), and various other components and their open source dependencies. These are low-level components that require a systems language which otherwise would have been implemented in C++.

> To date, there have been zero memory safety vulnerabilities discovered in Android’s Rust code.

> We don’t expect that number to stay zero forever, but given the volume of new Rust code across two Android releases, and the security-sensitive components where it’s being used, it’s a significant result. It demonstrates that Rust is fulfilling its intended purpose of preventing Android’s most common source of vulnerabilities. Historical vulnerability density is greater than 1/kLOC (1 vulnerability per thousand lines of code) in many of Android’s C/C++ components (e.g. media, Bluetooth, NFC, etc). Based on this historical vulnerability density, it’s likely that using Rust has already prevented hundreds of vulnerabilities from reaching production.

Source: Memory Safe Languages in Android 13 https://security.googleblog.com/2022/12/memory-safe-language...

But sure, keep telling yourself that it’s possible to write C++ code of this quality by being more careful or using some magical sanitizer or by hiring better developers or whatever.


"And the reality is that there are no absolute guarantees. Ever. The "Rust is safe" is not some kind of absolute guarantee of code safety. Never has been. Anybody who believes that should probably re-take their kindergarten year, and stop believing in the Easter bunny and Santa Claus."

Linus Torvalds - 2022

https://lkml.org/lkml/2022/9/19/1105


I didn't claim that Rust provides absolute guarantees. I don't know anyone who has claimed that. The only place I've heard that being claimed is people saying it's commonly claimed so by Rust advocates.

Even in my comment I quoted a passage that said "we don’t expect that number to stay zero forever". This is important. Although it has been successful so far, there will be bugs in it, even the odd memory safety bug.

That's still progress! Fewer bugs than before is progress, (mostly) eliminating a class of bugs is progress. I only addressed a person who was saying "there will still be some bugs, so there's no point tackling this at a language level". They're unable to grasp the idea of progress.


> And C++ just... doesn't have that many real problems.

From Carbon's README:

> C++ [...] is struggling to improve and meet developers' needs, as outlined above, in no small part due to accumulating decades of technical debt. Incrementally improving C++ is extremely difficult, both due to the technical debt itself and challenges with its evolution process. The best way to address these problems is to avoid inheriting the legacy of C or C++ directly, and instead start with solid language foundations like modern generics system, modular code organization, and consistent, simple syntax.


The question is not whether C++ has issues, it's whether the rest of the ecosystem cares about them as much as the Carbon devs, enough so that they would adopt Carbon instead of C++.

Carbon will face the same issue as Dlang. Everyone agrees that Dlang is an improvement over C++ in many significant aspects, and a very impressive one at that, but in order to gain meaningful adoption the benefit has to be high enough to justify the pain of swimming upstream against the rest of the ecosystem. D never quite made it above that threshold, though perhaps in an alternate history where Google picked it up instead of pushing Go, it could have.


D has two problems:

1. Being "C++ but nicer" is an awkward niche. It's not differentiated enough to overcome switching costs for C++ users. It's hard to justify risks of a new language, costs of hiring and/or code rewrites just for quality of life improvements.

At the same time being similar to C++ is a turn off for users who don't like C++ and look for something different.

2. D with a GC is not really competing with C++ in its core niche where C++ is irreplaceable, but rather with many many other GC languages for programs that can use almost any language. The idea of GC being optional is a hard sell, because it's an obvious switcheroo — without the GC you don't get all of the nice features, so GC-less D is even less differentiated from C++.

Carbon at least avoids the second problem. I'm not sure if Carbon's new syntax and semantic tweaks are different enough.


D's GC is optional. You don't have to use it. You don't get all the D features without the GC, but you do get everything that C++ can do.

One unnoticed feature of D's GC is it enables safe memory allocation when doing CTFE (Compile Time Function Execution). This can be used even when the code being compiled for runtime does not link in the GC. It greatly increases the power of CTFE.


Can I disable GC on code which was written with the assumption that GC is enabled? (Honest question... I've never used D but I've heard about the GC being optional before, and I'm skeptical.)

That is to say, if I want to use a third-party library, and that library was written to use the GC, and I want to _not_ use the GC, can I use said library? Or does using it require that I enable the GC for my code as well?


As much as people want to claim that you don't need to use the GC with D, in reality D is a garbage collected language and you do need to use a GC if you want to use D.

As soon as you disable the GC in D, you end up with a really awkward to use language, no closures, no exceptions, no dynamic arrays, I think you can't even use the common string in D without the GC.

People arguing that D can be used without a GC are just trying to sell you on something.


> no exceptions

There is a flag to allocate them with malloc, and use RC.

> no dynamic arrays, I think you can't even use the common string in D without the GC.

Totally not true. You can't concatenate arrays (string are just arrays of char) with `arr1 ~ arr2` and you can't `new` them, but you can do pretty much anything else.

> People arguing that D can be used without a GC are just trying to sell you on something.

Of course, but C++ people have an unnatural aversion to GC also the D GC only ever collects if you allocate from it. No allocations == no collections.

For the most part, GC is a productivity enhancer, you can roll your own allocators, use malloc, etc. if you need to. You can statically ensure that some or all of your code doesn't use the GC and as expected there is a productivity/code maintenance price you pay for doing so.


You can absolutely argue the benefits of a GC, and there are plenty of GC'd languages that as you say are great productivity enhancers.

If anything, D should stop pretending that it doesn't have a GC and stop trying to appeal to people who don't want a GC, it's a losing battle. D should just accept the fact that it is a GC'd language and start making the argument for why it's a better GC'd language than Java or C# or the host of other GC'd languages.

The vast majority of C++ developers do not want a GC'd version of C++, but it's possible that Java developers could be interested in a C++-like language that has a GC and good C compatibility.


D is not a xxxx language. It enables programming in many diverse styles, styles that some languages are totally dedicated to (like Haskell is to functional programming).

GC is just one of the styles.

Yes, if you use "new" you get a GC allocation. But nobody makes you use "new". If you use the array concatenation operator, it uses the GC. But there are many ways to concatenate an array that don't use it.

As for closures, they get allocated on the GC only if they escape the stack frame. This is detected, and if you want to be told about it, annotate the function with @nogc.


You are absolutely right. GC can be an advantage and there is no need to be ashamed of it. Herb Sutter is working on "syntax 2" for the C++ language and wants to have GC smart pointers in C++. The D creators should work on improving the GC so that it does not force pauses instead of explaining that GC does not have to be used.


>There is a flag to allocate them with malloc, and use RC.

What is that flag? Do you have a link to the documentation? I do remember talk about adding a feature that would allow exceptions to be allocated in @nogc code, but that was never ultimately implemented and looks to be postponed (to the best of my knowledge).


> to sell you

D is free to use for any purpose, being Boost licensed. We don't even keep track of who downloads it. Not that such info would do any good anyway, as anyone can host the distributions for download.

So yes, you can secretly use D at work, and we won't be able to tell on you!


You can disable collections being run, but if the library uses the GC, then it uses the GC!

(Lots of D users use a mix of GC and explicit allocation. Each has their best use cases.)

May I ask what your concern is?


I can’t speak for the parent, but I know there are programs that avoid garbage collection due to pauses affecting the business logic. I think developers in those situations often look to C, C++, or Rust as any particular library you reach for isn’t going to be introducing GC into your program.


The D's GC collection cycle does pause, but it does not run unless the GC is asked to do an allocation.

Hence, if you don't do GC allocations, or at least do not do them in your realtime loop, it will not pause.

D is not a GC language. It's a language with an optional GC. (It also does not have the code gen compromises that fully GC languages rely on, such as write gates.)


I don't know if you've noticed my previous comment already said D's GC is optional?

To me optional GC is a major downside. Because the option to use the GC exists, I don't believe that the language and the library ecosystem will have first-class support for the no-GC users. For example, DUB's website doesn't have an option to search only for no-GC packages. I don't want to be restricted to the worse half of the language.

Doing everything that C++ can do is not a reason to switch away from C++. C++ can already do everything that C++ can do.

D has some nicer syntax, and neat little features like universal function/method call syntax, unittest blocks. But I can't go to my boss and say "Hey, we should rewrite our product in D. Why? Because the unittest block is a really cool idea".


> Why? Because the unittest block is a really cool idea".

Indeed, you should not change languages based on only one thing. It's also pedantically true that one can do anything in any Turing-complete language.

A much more interesting point is how productive one can be in different languages.


Anecdotally I think the answer is "yes!!!"

A little over a decade ago the industry (of people that cared about C++) were psyched about C++11. Today people don't really give a crap about C++20 other than checking that their code still compiles and people barely know what's in C++23. The air has been let out of the balloon, since other ecosystems have grown up and are easier/better to use than C++.

I know of multiple shops that would have "never" moved off C++ that have switched to C# or Go. The performance is there and the headaches aren't.

And frankly, C++ doesn't have an ecosystem. There's boost, abseil, folly, and to an extent Qt. Everything else is C and wrappers around C. Moving off C++ means adopting a language with a good standard library and/or an actual ecosystem that does useful things - which C++ massively lacks.

Rust is definitely in the wings and growing, it's just a shame that so much of the industrial use turned out to be crypto. Once C++ developers get over their irrational fear of generic programming and package management, Rust and it's ecosystem become extremely compelling.


The fact that Rust has an ecosystem kind of hobbles it. C and C++ are often used in basically all the other ecosystems because that's what they are for.

C and C++ don't have a fear of package management. On the contrary, they're packaged in more ecosystems than probably anything else: gems, wheels, rpms, debs, nix, conan, vcpkg, you name it. The hard part of C and C++ packaging is making it easy for projects to integrate in all those ecosystems.

If carbon goes the same route as Rust, Go, etc. by standing up yet another hermetic ecosystem, it will be very clear that it's not really trying to replace C and C++; it will merely be trying to carve out a new niche.


I am convinced that had Java and C# been Delphi like in, a RAD environment AOT compiled by default, with the performance focus that only now they are having due to Go and such, and probably not even C++11 would have mattered that much.


> Carbon will face the same issue as Dlang

I think one thing that Carbon has going for it is that it's bidirectionally compatible with C++, in the same way that Kotlin is with Java (or Swift with ObjC). If you have a massive C++ codebase, you're supposed to be able to just add new Carbon code, without changing any of your existing codebase. This should allow gradual adoption at whatever pace you want, which should help adoption a lot.


Is it? Can you replace C++23 code with Carbon? Will it work with C++ modules? Will the existing find_package calls in downstream C++ CMake projects work?

I'm waiting for some other shoes to drop here. There's some fine print in this promise that isn't widely grokked yet.


It should have enough compatibility with C++ that Google and others will be able to incrementally migrate their C++ code. So C++ modules should be supported.

Code migration is part of the Carbon language requirements. Carbon is being designed because other existing langages didn't focus on this aspect.

The specific details and edge cases are probably to be determined.


It's fine to have a goal for general purpose compatibility with C++, though that's harder than it sounds. More than likely there will have to be lines drawn in the sand like "no ABI compatibility ever" or "assumes you're using only clang toolchains" which will necessarily limit how generally adoptable the language is.

It's clear that compatibility is a goal but it's clearly not a feature yet, so we should be careful to talk about carbon as if it has that feature, especially given how hard that feature will be to implement and support.

I'm more confident that Google will be able to meaningfully use carbon in its monorepo than I am that it will be a good replacement for C and C++ for any given non-Google project.


Google's is mostly happy with C++17, as per their guidelines.


Carbon will likely help C++ because now there is a new playground to iterate on new ideas and then when they stabilize then C++ can decide to just copy it.


The problem is that people take for granted that [insert code organization method here] is good and lack of it in another language is bad. This is a rehash of the conversation between Java and C++ proponents about the correct way to do multiple inheritance.

In practice, none of this really matters. For example, generics are just one way to do code organization, you can write codebases that are clear, maintainable, and reliable, without ever touching generics once.


None of those are 'issues' for me. The language isn't perfect but the Carbon approach seems to not solve any meaningful issues.


> And C++ just... doesn't have that many real problems.

I can honestly say I've never known anyone who has written a lot of code in both C++ and some other language who has this opinion. I'd say, to the contrary, that almost every feature and characteristic of C++ is a problem - it's either a complete disaster in terms of programmer ergonomics or it makes it way too easy to create terrible bugs. It's _all_ wrong.


I write of code in both C# and C++ daily, have been doing it for ~15 years now, and maintaining an ancient codebase. I generally agree with TheRealPomax. C++ has problems but I personally find it more ergonomic than Rust (less than C# though) and I personally never had a memory issue in my own code. In other people's code, yes, there were some subtle ones, but I usually found those pretty quickly. It's not a perfect or even a good language, but IMO not a complete disaster.


I have this opinion. I much prefer C++ to Go and Rust. There need to be languages that don’t hold your hand - you can argue instead that C++ is an incorrect language choice for many projects and I’d agree with you though

Once you understand lifetimes well C++ is a joy to write. 99% of all the complaints about C++ are 1. lack of automatic bounds checking, which is trivial to implement yourself 2. memory management problems because people have a poor mental model of how it works, which can be learned.


> 99% of all the complaints about C++ are … 2. memory management problems because people have a poor mental model of how it works, which can be learned.

or memory management problems because Qt uses a different string type than glib uses a different string type than std, each with different ownership semantics, and by the way some of these claim to be thread-safe while others don’t say clearly one way or the other in the docs, except actually Qt’s copy-on-write implementation claims to be thread safe but assumes that the compiler inlines the mutation operators so if you forward-declare `struct QString` instead of #include <QString> then the operations might not be thread-safe…

i think the CoW problem might have been with Qt’s set type, not its string type, but you get the idea. it’s not just the language: it’s the library ecosystem too. it’s that any time i dive into contributing to a new C++ project i have to learn potentially a new memory model, one which is likely assumed instead of documented.

RAII presented an opportunity to normalize all this stuff; i’m not sure how significantly it’s unified things: i suspect it’s effective primarily in greenfield projects.


> Qt uses a different string type than glib uses a different string type than std

That is true for any language, even C, so your complaint is with those libraries not the language - and glib isn't even a C++ library at all while Qt is an ancient library that cares more about source-compatibility with its earlier versions than modern C++ (or even any version of C++ with a std::string).

> except actually Qt’s copy-on-write implementation claims to be thread safe but assumes that the compiler inlines the mutation operators so if you forward-declare `struct QString` instead of #include <QString> then the operations might not be thread-safe…

That doesn't make any sense. How is inlining going to affect thread safety? And (only) forward declaring a type won't let you do any mutations since at that point it's just an opaque name withoutout any known members.

> it’s not just the language: it’s the library ecosystem too.

And a new language won't fix that - especially when your idea of the library ecosystem for C++ already includes C libraries.


> glib isn't even a C++ library

glibmm

i’m sorry that i’m fuzzy on my Qt CoW issue. it was 8 years ago or so, i could probably dig up the ticket about it but the point was that thread-safety is just a thing you’re guessing at whenever you’re using C++. other languages have radically reduced that guesswork.

>> it’s not just the language: it’s the library ecosystem too.

> And a new language won't fix that - especially when your idea of the library ecosystem for C++ already includes C libraries.

that doesn’t match my experience. taking the C++ codebases i’ve contributed to, more use a non-std string type than do. e.g. LMMS uses QString, Stepmania uses its “rage” rstring type. neither of these are small projects, both have download counts in the multi-millions.

new languages do address these problems. when i see a project in Rust (or Go, Typescript, …) that i’m thinking of contributing to, i can be fairly confident it’s using the standard String type and that i can come up-to-speed on its memory model instantly — when i see that same project written in C++ i don’t know if it’ll take 10 minutes or 10 hours to understand its memory model, and believe me that uncertainty does impact which projects i choose to contribute to today.


You did not claim that C++ had no problems, just that you prefer it. No fight from me. You should be able to like what you want.

While not a shot at your choice, a C++ dev that I follow a bit is the creator of SerenityOS. Many times and in many of his YouTube videos he has sung the praises of C++ and called it his favourite language. Presently, he is writing his own language, Jakt, to replace it. I find that interesting.


>memory management problems because people have a poor mental model of how it works, which can be learned.

But that has to be learned for each CPP file separately.


> Once you understand lifetimes well C++ is a joy to write.

Well, so is Rust. You even have usable macros and templates that are't cancer to write.


Hi, I disagree, nice to meet you

I wrote plenty of code in Qt and C++ (up to around C++11) and I don't think it was that bad. I then moved on to JS / PHP (purely for money) and now Rust.

C++ is not that bad. Templates can be a bit hairy and slow.

Now that we have Rust to compare, having safety would be nice. It wasn't an option back then. You were either shooting yourself with undefined in scripting languages or with null pointers in C/C++. Having a dependency manager a-la npm or cargo would be nice, but it was never an option in the past.

But things are mostly fine.


> So based on the article's own observation: no, of course not.

This had very little to the discussion. Of course it can't be replaced. Code is created by humans, and as long as we have opinions nothing gets truly replaced. Just decreased usage over time.

> C++ and Switft just became "more dominant".

Yup, like this. Of course a general statement is no.

I have very little interest in this topic. But I seen this SAME comment a million times on anything thats new that attempts to challenge something. And as usual whether something "dethrones" something is less interesting than what changes or ideas that it offers.

Just like ALL those you listed, they didn't replace any of those, but they definitely challenged the ecosystems, or improved the old ones.

Naunce discussion is far more interesting.

For example, why do you think Carbon won't be able to gain dominance over time? I mean I think thats a huge hurdle too.


You've apparently read the reverse of what I said. I said the new thing didn't replace the old thing, and that therefore the idea that "we are doing the same, and it will replace the old thing" is nonsense. I did not say that because it can't replace it, it is therefore not worth doing. It absolutely is, like all attempts at making things that "solve the problems that C++ has" have been varying degrees of worth it. But the idea that it can, let alone will, replace the original is such an obvious "no" that the title is clickbait. Or slide-bait (since it was originally a conf. talk)


Of course, I agree that C++ isn't going to entirely disappear, but I don't understand what you mean by "C++ doesn't have many real problems, only irks". Surely the lack of memory safety is more than a mere irk--certainly Mozilla felt strongly enough to develop an entirely new programming language (as did Carbon's developers), and of course entire domains have moved away from C++ entirely (often in favor of GC languages). Yes, there remains some contingent of people for whom things like "deterministic memory management" or "immaturity for $domain" are bigger problems than those presented by C++, but that doesn't mean that C++ is without real problems, right?


Your definition of "replace" is too strict: the idea of a successor language is not replacing all existing code, but rather making it possible for individual projects to painlessly evolve from the old language to a new one. Some old code - whether entire inactive projects or inactive parts of active projects - may never get rewritten in the new language and that is OK.


"Replace" ought to at least mean, new projects don't use the old thing.


> Swift didn't replace Objective C

Give it time. Unlike the other examples one company (Apple) has full control here. There is basically zero demand for Objective-C outside of development for Apple platforms.

Apple is already making Swift only features and APIs and is deprecating older things. Obj-C is arguably legacy already, but still works fine.

I’ll bet plenty of money there will find a day when Apple says “This is it, next release it’s out of the toolchain”.

Existing developers often have Obj-C code (I do), but the biggest user is Apple. So they can’t kill it tomorrow. But its days are numbered.

No one is in that kind of position with C/C++/JS/Java.


One exception is Metal, it is actually implemented in Objective-C with Swift bindings.


> or C lead to C++,

As "Unix haters handbook" says: C++ is to C, what lung cancer is to lung.


A profoundly idiotic statement, but on-brand for that manifesto.


I love how it ignores that C++ was developed on the same place, even on the same corridor as C and UNIX devs used to work.


And yet ... the C developers were never impressed by C++, and (for instance) Plan9 ended using a differently enhanced version of C, and never (I think?) had a C++ compiler.


The same developers that came up with Limbo and Go, somehow there is a common trend on how they see language design and the alternatives.


YMMV but Go is one of the most divisive tech out there for me.

I like C++ and Rust. If I meet a dev who likes Go, I can guarantee we won't agree on much.


If a language helps a developer create a solution, it is fundamentally not a cancer.


> As "Unix haters handbook" says

As they compile their C code using a compiler written in C++. (GCC and Clang are both written in C++).


To be fair, that wasn't true when the Unix haters handbook was written, almost 30 years ago.


Nonetheless it was true that C++, C and UNIX share the same birthplace.


> And C++ just... doesn't have that many real problems.

70% of security bugs are memory safety issues. That's a lot of real problems.

> It has a lot of irks, but the problems people run into are problems that others already solved, a thousand times, over the last half century, in many different ways for many different iterations of the language.

People run into memory safety issues more often in new C++ code.

https://www.chromium.org/Home/chromium-security/memory-safet...

https://security.googleblog.com/2021/09/an-update-on-memory-...

https://github.com/microsoft/MSRC-Security-Research/blob/mas...

https://media.defense.gov/2022/Nov/10/2003112742/-1/-1/0/CSI...

https://media.defcon.org/DEF%20CON%2030/DEF%20CON%2030%20pre...

https://advocacy.consumerreports.org/research/report-future-...

https://alexgaynor.net/2020/may/27/science-on-memory-unsafet...

https://github.com/google/sanitizers/blob/master/hwaddress-s...

https://security.googleblog.com/2022/12/memory-safe-language...


> 70% of security bugs are memory safety issues. That's a lot of real problems.

Run your code in a WASM sandbox or on a GPU, problem solved.


"Run your code in a WASM sandbox" and then your C++ is way slower (and speed is the only reason you were using C++ in the first place)


C++ compiled to wasm is just java with extra steps.


I totally agree but there are two differences:

- WASM will be available even more places than the JVM

- way more languages will target WASM than ever did the JVM

Personally, I cannot wait for a WASM future.

Being able to target WASM for the 90% of apps that it is fast enough for and being able to use the same language and libraries to target native when required….is going to be awesome.

I really like the CLR. A more widely adopted version of something similar ( WASM ) is attractive.



Unless you write software that processes input from one user while having data private to another user in memory. So ... quite a lot of software


Which is quite risky even with memory safe languages, if the big exploits in the last decades had anything to show it is that both RAM and CPU can be abused into bypassing any protections in place.


> Run your code in a WASM sandbox

Assuming your WASM sandbox is airtight, that would work. But there are still ways to break out or cause damage because within the sandbox, its like a flat address space with 0 modern protections like ASLR, stack canaries, page protection, etc. (unless you manually compile it in yourself). See [0]

* [0]: https://www.usenix.org/conference/usenixsecurity20/presentat...


There is a lot of code that can't run in a WASM sandbox, like drivers for example.

I do think more things running in WASM or WASM-like VM's could help a lot, but I'm not sure what the GPU part is supposed to mean.


>70% of security bugs are memory safety issues. That's a lot of real problems.

Are these really real enough problems, though? If you're defending against state level attackers it's a problem. But how much do these really impact Joe Schmoe average computer user?


Please don't go this way.

People targeted by state level actors are people too, and software should protect them if it can, and not having mem related bugs is definitely possible :)


What makes you think state-level attackers cannot affect you? What if they hack a hospital and leak your medical data or mess with life support systems? Or make another train derail in Ohio, or disable another pipeline with a little hack in the middle of winter?

If you oppose change so much that you just shrug in the face of free 70% reduction of risk I don't know what to tell you.


It's real enough for nearly every company or higher value software target... so, yes, it's a real problem. For that matter, it's real for every person using a computer on the internet.

You don't have to be the final target to be a botnet node... you don't even need to be a specific target to get a keylogger that tracks your logins for financial websites.

Yes... it is REALLY REAL ENOUGH,


Sorry, did you mean encryption ransomware? Or DDOS bot swarms? Or crypto mining hijackers? Or corporate sabotage? Or….

Because I think the answer is all of us.

Also, the targets of state level actors are using the same software as the rest of us. If ours is insecure, theirs is too. Have you seen the list of Open Source vulnerabilities the US Gov has not patched?


no language is ever going to be 100% replaced, but C++ has largely replaced C and Swift will likely largely replace Objective-C. this article obviously isn’t discussing whether something will wipe C++ off the face of the earth but that it might replace most of its use cases. why are you nitpicking over the word replace?


Languages do get replaced. It is just taking them longer and longer.

How much ALGOL do you see out there?

There will be almost no Objective C at some point.

There will be almost no Visual Basic.NET at some point.

A C++ replacement may take longer than the rest of my life.

It is possible though that we may not be that many years away that, for new projects, it may be uncommon to choose an “unsafe” language.


I'm with you but you lost me at the car analogy.

Be careful with that, because it only takes government to decide to heavily tax something or simply phase out something for it to go away. Eventually the minority cost rises so it becomes a self full-filling prophecy.

That, will not apply to C++ or languages in general.


I will not be careful with that at all because I didn't restrict my statement to "some country". I said cars, full stop, you're trying to replace cars on a planetary scale driving (a non-trivial part of) the economy of the entire planet, just as C++ is used on a planetary scale, driving (a non-trivial part of) the economy of the entire planet.

Could countries that currently don't really have cars? Yeah, probably. In the same way that a market segment that doensn't use C++ can decide not to use C++. Could a country like Vietnam? Doubtful, but maybe. A market segment with low C++ penetration can probably decide they want to collectively move away from C++. Could China? Not anymore, no. C++ drives too much software in the market segment to make sense to replace, even if the grass is greener on the other side of the language fence. Could the US or the EU ban cars (and again: not ICEs, but cars, full stop)? Let's all try not to laugh.


Your threshold for "replace" is too high. Did cars not replace horses because horses still exist?


Worse still in this enumeration, TypeScript isn't a replacement like the others at all: no major js platform (browsers, nodejs) supports it. (here the term "native support" is thrown around a lot, but I feel at this point you're already well in llvm territory with the definition of "support")


I'd argue Swift has replaced Objective-C, for new code. Or will soon. If Carbon does the same vis-a-vis C++, I'd say they've succeeded in "replacing C++".


Only because the platform's own says it is my way or the highway, Carbon authors don't have this leverage.

Just like Kotlin hardly matters outside Android.


You are still free to use Obj-C for new projects... for now.


Betteridge's law holds up as usual.


It'd be quite nice if HN automatically flagged that to submitters. "Please rewrite this title to describe the article, as it is currently a question and the answer is no".


Has anyone else looked at Herb Sutter's cpp2?

For those that don't use C++, Herb is chair of the ISO C++ standards committee, and holds the position of "native languages architect" at Microsoft.

https://twitter.com/herbsutter/status/1609307537261617154

This is a good introductory talk on cpp2 by Sutter at CppCon three months ago, where he demonstrates cppfront, the cpp2 -> C++ transpiler. One of the things I like about it is that the code it generates is human-readable and fully backwards-compatible with C++. If you use cpp2 in your project and end up not liking it, you still have the same (very reasonable) C++ code that you'd write by hand today if you followed the guidelines you're supposed to already.

https://www.youtube.com/watch?v=ELeZAKCN4tY

I think this is very promising, and I'm interested in using it my next project. We don't need a total replacement for C++, we just need to let out the awesome language that's always been hiding inside it.


That's the wrong direction. What's needed are intelligent converters which convert less-strict languages to more-strict ones.

Non-intelligent converters just make a mess. Here's c2rust.[1]

Classic C++ to modern C++, plus a compiler flag to lock out all the old unsafe stuff, would be an achievement.

[1] https://c2rust.com/


Have you actually watched the talk, or are you just giving us yet another ad for Rust? cfront helps C++ developers switch from less-strict C++ to a much safer, much improved syntax known as cpp2, which may in the future become part of the C++ standard.

I like Rust well enough, but I'm simply not interested in abandoning C++ and all of the incredible stuff written in it just for the sake of theoretical purity and safety.


He didn't staff a team of compiler engineers to do it. Doesn't matter how good it is when mature languages that reach the mainstream all have compilers funded by 10 people at a tech giant and cppfront is just Sutter screwing around in his free time.

Google threw the weight of their top C++ engineers behind Carbon. It's happening. That's really what matters in the world of programming languages. Not how good it is.


Just watch what happens to Google and their ad revenues in this downturn, by the way. I knew people that were hyping Fuschia, and then Google cut deepest from that on their first round of layoffs. It wouldn't be a shock to me if they yank out the carpet from this Carbon thing one day, or have it limp along like Dart.

In summary, Google can do what it wants, but I'll just keep using C++ no matter what it does. I spend all my time in and on HaikuOS now, so for me C++ here here to stay :)


It's good to see that you're having fun with Haiku. I actually enjoyed programming for Haiku a couple of years back on my Haiku only project (Medo), these days I'm 100% exhausted with my day job (and my previous company went into liquidation and I changed jobs / continents), and it's hard to make the time for passion projects.

Best of luck with your project, I look forward to seeing it released one day.


Whoa cool! Medo is awesome!

Thanks! I'm working on a port of Solvespace to Haiku. My goal is ultimately to give it a native UI and some new features, but I'm still early in the process. The latest thing I got working was some pixels in the screen from a replacement 2D renderer that uses AGG instead of Cairo. I post screenshots to Twitter as I go (@realtaraharris).


Why do you think Dart is limping along? It has a very large team working on it and a very popular framework built on top. I think it may even be more popular and get more investment than golang. Google would probably be happy if Carbon is as successful as dart.

Also being dismissive of Fuchsia being a dead end despite contributing to Haiku seems a bit ironic.


Fuschia is open source, so no matter what Google does in this downturn, you can still use Fuschia for your needs.

https://cs.opensource.google/fuchsia


There’s “meets my needs today, which include a belief in the ling term viability and talent pipeline”, and there’s “the small project I wrote can keep running on obsolete hardware forever”


Fuschia is shipping on Nest devices though.


It's on a device that is unimportant to Google, and it's just an implementation detail. Fuschia could disappear entirely in one software update, or with cancellation of the Nest product line.

I like the ideas Fuschia is trying to implement, but unfortunately it still looks like a small experiment with an uncertain future.


Even if it dies tomorrow, it already achieved more than many wannabe OS out there, so there is that.

And who knows, just like it happened with Singularity and Midori having an impact on .NET design since WinRT, some Fuchsia ideas can be brought into Android in that case.


> Google threw the weight of their top C++ engineers behind Carbon. It's happening.

Google throws their weight behind a lot of projects. You can find a list of 282 of those projects here: https://killedbygoogle.com/


> Google threw the weight of their top C++ engineers behind Carbon. It's happening.

Google has a notoriously short attention span.


The thing is, Sutter's approach is much more sensible when looking at real world adaptation. You can start using the cppfront transpiler, and importantly, if it doesn't work out, you can just use the C++ code generated by cppfront (which Herb Sutter said is meant to be idiomatic and human-readable). From a risk perspective, a developer will have a much easier time convincing a manager to try using cppfront instead of Carbon.

Maybe once Carbon reaches a stable 1.0 release and has seen some success in production (~2026 maybe?), that point won't be as important, but especially in the beginning it seems to me a deciding factor.


Carbon is explicitly marked as experimental and is not used yet at Google. The contributions from Google can be stopped at any time.

So it's too early to say that "it's happening". Right now, it's just an experiment.


Yeah, he tries to sell cpp2 as being different to the other alternatives, due to his position at ISO, however it is just the same thing being an alternative language, compiling via C++ translation doesn't change that.


The thing I like about it is that it is the easiest thing to switch to. It provides the path of least resistance for my existing workflows, and that alone is reason enough for cpp2 to win.


That would be Circle, not a language with another syntax.


Circle is nice, but it's not integrated with anything but compiler explorer. Cpp2 has a preliminary CMake integration PoC as of a week after Sutter's talk.


CMake isn't the only build tool in town, I hardly use it for example.


My point was that whatever build system you are using doesn't support circle. The CMake thing was an example to illustrate and contrast.


No.

Carbon is an experiment to solve Google's challenges with C++, which look very different to, say, the challenges of the games industry or those of embedded software development. C++ is widely used enough that it would take decades of sustained development specifically targeting replacing it across all the areas it is used to make a dent.


Indeed. C++ will be displaced (not replaced) by the usual suspects: Rust, Zig, Golang, maybe even niche languages like Nim in certain areas, where C++ used to be the only sane choice.

It's a bit like Fortran has been displaced by C, C++, Julia, even Python (with Numpy / Scipy) from the realm of numeric code where it used to reign supreme. It does not mean that important Fortran code does not exist any more, or even that new Fortran code is not written every day. It just means that Fortran is no longer dominant, and in many areas is definitely not the first choice.

Same is happening to C++.


As one data point: we are replacing Golang with C++ for homogeneity and not-weirdness. C++ has problems but it is very good at scaling and being boring, which is a good thing.


New Fortran is written all the time though. It might even be as much Fortran as was written in it's heyday. Programming is much, much bigger than it used to be.


Certainly! Fortran is just not the only game in the numerical town, and likely it's not dominant any more, but it's alive and kicking.

(Well, new Cobol code gets written.)


Last time they tried to replace C++, it was with Golang.


If I recall, Golang was made to make fresh college graduates more productive. I don't know if large C++ code bases are a good place to get junior devs started, there's quite a risk that they'll introduce subtle bugs because of C++'s... C++-ness if you don't give them an in-depth course before putting them to serious work. C++ and Go are languages with different stengths, purposes, and use cases.

Golang only accepts one way of doing things and it looks like Python. It makes assumptions to replace complexity so you don't need to think too deeply in many cases. I would never pick it for any serious project, but as a quick one-off tool, especially if you're planning on networking it, Go can get the job done easily and painlessly enough.

Now, Dart, on the other hand, that's a language that doesn't need to exist in my opinion. It's ES5/ES6 with some tweaks but IMO TypeScript has since easily surpassed it at a language level. I don't know why Dart still exists, but we're stuck with it now that Flutter uses it.


It was made by veteran SWEs frustrated with C++ in whatever level of code that it was too pedantic for. I think it was targeting all that stuff that was written in C++ rather than Java for performance reasons but could still use bounds checking and GC. Pretty specific use case. Java, Python, or JS will still be a lot quicker to work with for higher-level things or quick scripts.


Well hopefully they learned something :)


Exactly…


Low effort take from gamedev: to start talking about replacing anything Carbon needs to start presenting 'solutions'. The only thing they presented so far is their inability to work with others.


Any successor to C++ will necessarily need to be built around safety from day one. Carbon did not do that - it merely hopes to put safety in at a later stage. So no, I don’t think Carbon will replace C++.

I will be very surprised if a C++ successor will be a new language. I think it will be a frontend to C++ that cleans up the syntax, has much stricter rules around UB, and can rely on C++ as its unsafe counterpart. C++ itself will never be safe - it can’t be while maintaining backwards compatibility, and even modern features (ranges, coroutines) provide a wide range of new lifetime nightmares.

A new frontend could solve a lot of that, while allowing unsafe “trust me bro” code to be written in C++.

There’s the “enable new features in a file with pragmas” idea, too, which could be promising. But I’m not convinced.


> frontend to C++ that cleans up the syntax, has much stricter rules around UB, and can rely on C++ as its unsafe counterpart

You're looking for Herb Sutter's CppFront: https://github.com/hsutter/cppfront

As Cfront was to C, Cppfront is to C++.


Syntactically, I find cppfront gorgeous.

However, I’d like to have seen more emphasis on safety by design, rather than safety by excluding things.

I think it’s definitely easier to get it in at this stage of cppfront’s development than it would be of Carbon, but that’s because the implementation is incredibly simple and the technical debt is low.

I have high hopes for cppfront, though. I hope it grows into a full frontend rather than a preprocessing step.


It's very opinionated and SerenityOS-focused, but the language Jakt ( https://github.com/SerenityOS/jakt ) transpiles to C++, has memory safety and some very neat ideas for readability.


I love the SerenityOS project, the subprojects, and the passionate people behind it, but I doubt Jakt is going to get any more serious use than most other toy languages. I think Jakt will be as much a production programming language as SerenityOS will be a production operating system.

Interoperability with C++ is a very nice and useful thing but the language still needs work. Andreas' video on writing code that actually does stuff in Jakt made it clear that there are still places where the language needs to be improved (which is fine, it's not finished) and at its current state I think it'll be a while before the language gains any adoption.

The language reminds me of Zig in a way, which also featured a "transpile a language into another" approach up until recently. Unlike Zig, Jakt actually seems to have usable syntax highlighting and IDE support beyond "highlight these specific keywords". I've never found any IDE that works well with Zig, and the people I asked told me to use an older, buggy highlighter and ignore the errors or program without any IDE support.

Despite its immaturity, it's already nicer to just work with than the language behind Bun, a JS runtime mentioned here on HN a lot. That's very promising for the future of Jakt at the very least.


Yeah, I neglected to mention that it's nowhere near finished, but it's under heavy development and the interoperability with C++ means there's a low barrier for adoption, so who knows?


Unsafe rust code is "trust me bro" too


Exactly! And yet Rust gets a reputation of safety: the boundary between safe and unsafe is formal, and that opens up huge possibilities for metrics, compliance, and targeted testing. That’s what I’d shoot for.


People say this a lot. But formal methods is really hard and really tedious. Especially if you can't write whatever you're trying to prove safe in safe rust, it's going to be even harder and more tedious.

To give perspective: CompCert (a C compiler with formally-proven semantics, arguably one of the largest formally-proven programs to date) has been developed for decades and still does not support all C99 features; it and sel4 (a formally-verified safe microkernel) are both single-core because proving properties in complex multicore interactions has basically not been done (sel4 actually does have a multicore implementation, but it's not yet formally verified).

Safety, performance, ease-of-use: pick two. If we really care about safety, the easiest solution for many is to just use a language like Java or Python where everything is boxed and checked and there is no truly unsafe code. Safe Rust strikes a really nice balance of being almost formally-proven safe, almost as performant as unsafe Rust/C++, and almost as easy to use as more general-purpose-languages (the extent of the third "almost" varies widely among developers).


Except it is not though. Unsafe blocks are "hey check this extra carefully because it might be unsafe" instead of everything being implicitly unsafe everywhere.


Also worth reading: The Year [2022] of C++ Successor Languages [0]

"interface" seems a step forward, amongst other things. I'd like to see Sumtypes (aka Algebraic Data Types) without the pain. And recursive data structures. And co-routines for mortals.

I'd be tempted to check out Carbon at some point. I am mistrustful of Google, though, what with their whole telemetry idea in Go.

A good outcome would be if Carbon pollinated some ideas into C++, acting as a testbed.

I think that C++ has steered itself exceptionally well, actually. It has aimed at stability rather than "move fast and break things". It has avoided the missteps of Raku (Perl 6), Python 3. The fact that people "hate" C++ is on balance more of a feature than a bug. The newer languages have projects which sometimes mandate nightly builds (I'm looking at you, Rust and Zig). It feels that you're trying to build a house on a sandbank.

I hope that C++ never gets a package manager/build system. I'm not convinced that they've ever really been done properly or stably (Python seems to have a plethora of install methods, for example), and it leads to the mentality of kitchen-sinking dependencies.

[0] https://accu.org/journals/overload/30/172/teodorescu/


> It has avoided the missteps of Raku (Perl 6)

It is unclear to me what missteps you are referring to?


It took over a decade to produce. After all that, it was pretty damn slow, and I suspect that many people thought it was too slow to be worth using.


Well, performance has been improved by several orders of magnitude since the first release. So maybe it's time to look at https://raku.org again (or first have a look at its new documentation site https://docs.raku.org)


> Dart is a language on top of JavaScript

Isn't Dart a compiled language that can be compiled to JS via dart2js and not "on top of JavaScript"?


Yes, at first it reminds me a bit of Haxe [0], which compiles to a multitude of languages. Originally it was made to "replace" JavaScript, there's Angular Dart for instance as an example of what that would work like. But nowadays Dart can compile to JavaScript or "Dart Native" [2] which instead of Haxe reminds much more of Java or C# since it runs inside a VM in JIT mode.

It can run on ARM32, ARM64 and x84_64 natively as machine code through the Dart runtime when compiled AOT and performance is of course much better than compiling to JavaScript so you can see why it's a really interesting option for the development of Flutter which targets web, desktop, and mobile. You write the code once and get to have JIT for development with hot reloading, debugging and live metrics, and AOT compilation for your desktop and mobile targets while also getting a JavaScript bundle for your web target.

[0]: https://haxe.org/

[1]: https://github.com/angulardart

[2]: https://dart.dev/overview#platform


Worth noting Haxe can also compile to bytecode that runs on the HashLink VM.


Originally it was built on top of v8 itself if I'm not mistaekn, so the author might be referencing some historical knowledge that has kind of changed.


> it was built on top of v8

Was never built on top of V8 in any shape of form. Dart VM does not even share any code with V8.

Dart 1 was designed by people who originally started V8 (Lars Bak and Kasper Lund), that's the only connection.


Seems I too may be misremembering as well, I do know there used to be a custom Chromium build that included a Dart runtime so I assumed that was why v8 was used. But I remember now, there was an original effort to include dart in Chrome which met no fanfare.


yes, Dart has little to do with JS now, it's made for Flutter for the most part nowadays, and it is great.


Reading the article, it mostly looks like syntactic sugar changes. Is there more under the hood? Most of C++'s problems are on the data side. Newer versions of C++ address the big issues (How big is it? Who deletes it? Who locks it?) but only by adding features, not by deleting anything. What is Carbon doing in those areas?


Maybe there are too many (C++)++ languages? So its too hard to pick a winner.


Almost always the probably, almost certain answer to an essay like this is a "no."

Google could focus on making C++/Rust interop as smooth as Carbon's instead.



Exactly. Thx for the heads up.


>Almost always the probably, almost certain answer to an essay like this is a "no."

Betteridge's law of headlines


You're well informed, sir/madam. :)


why does every attempt to replace C++ make syntax of the new language significantly uglier than C++?

why do I need to type "let" and "fn", etc?

why not make the syntax very similar if you actually want to make it easy to migrate?


It's somewhat related to solving one of C/C++'s real problems: the syntax is very context sensitive. That makes tool development harder.

Personally I think it's great that most new languages seem to move in roughly the same direction when it comes to syntax.. like

"x: int" instead of "int x" for variable declaration, and something similar on functions "fn", "fun" or "function" prefix before functions "let"/"const" for constants and/or single assignment variables "var" for variables etc.

I think there's a reason so many language designers are making similar decisions on these things.


why is this great? what's the reason? x: int is significantly less readable than int x and involves typing one more character. Why?

what is the advantage of type int fn foo versus int foo() {} ?

why type var in front of a variable when int x makes it clear its a variable?



“Significantly less readable” is subjective.

It is simpler to parse, and degrades better with type inference. That’s 90% of it, I’d imagine.


sure, well, it's not subjective if you have to type more characters to basically achieve the same thing. I guess I just don't really understand why you have to fix C++ shortcomings while also changing things that work fine. Is there a C++ developer who is having trouble declaring variables as int x?

By making big changes to syntax, you are just making it less likely this ever gets truly adopted.


Simple types may be easier, complex types are a real pain for both humans and compilers, and they end up hiding the name in the middle of the thing. Brevity is neither the only nor most important thing on which to judge syntax.


A language with good type inference lets you type less because you don't need the colon or the type, where as a language with it first you always have to type something like var for a "figure it out" type.


Something like "int* a, b" not doing what people expect it to do is a very common C++ footgun.


auto + implicit coercion + pass by value semantics and copy constructors create real bugs and pitfalls in C++ code. Avoiding these semantics and deferring to explicit syntax leads to better code.

Optimizing for character count is dead.


From TFA:

  // Returns the smallest factor of `n` > 1, and
  // whether `n` itself is prime.
  fn SmallestFactor(n: i32) -> (i32, bool) {
This is so unlike C++ I cannot see how anyone can consider it a successor language. It might, in fact, be a much better language, but it is not a successor when you're going to change syntax this much, and in a way that will be hard to automate (precisely because of the "most vexing parse" problem(s).


Is that really so different from the following C++ equivalent?

auto SmallestFactor(int32_t n) -> std::pair<int32_t, bool> { ... }


I guess I don't understand what role the -> plays there. I must be too old school, I suppose.


In this particular example, all it does is reverse the order of return type wrt arguments and function name. I still find this syntax more readable with complicated return types because you no longer have to carefully parse it to see where the type ends and the name begins.

In the more general case, having the return type follow the function name means that it can reference parameters in sizeof(), decltype() etc.


I can't speak for the C++ example, but in your code snippet `->` points to the return type. The function takes an integer argument and effectively turns it into a tuple, so: `f(i32) -> (i32, bool)`.


Swift is a successful successor to Objective-C and their syntaxes and idioms are worlds apart. It’s about what class of problems you can solve in the language.


I don't agree with your analysis. But that's fine.


Even C can't be parsed purely syntactically; you need to know whether or not an identifier names a type. C++ is worse: https://en.wikipedia.org/wiki/Most_vexing_parse


right, so some simplifications or improvements are fine, but it doesn't follow that we should now have to type var, let or fn everywhere - it just makes the body of code a lot uglier

auto time_keeper = TimeKeeper(Timer());

this is nice and clean


> it just makes the body of code a lot uglier

I’d suggest learning a couple more languages - after you’ve learned a few, you get used to it - you don’t even see the code. All I see is assignment, variable, parameter…

(But seriously, the vast majority of imperative languages have syntax which is near-enough the same that it really doesn’t matter - much like two spaces vs four spaces, you can spend days, weeks, months arguing about which is better… or you can flip a coin, pick one, and after 5 minutes of using it you’re used to it, freeing up your brain to worry about more useful things :) )


missing the point here, if the goal is to migrate people away from C++ to this new thing, it's easier. less error prone to keep syntax similar. That's why Java was so successful.


Copy constructor much?

(Also, I would take var over auto any day, to be honest; but no, they had to override the old useless keyword for some mysterious reason.)


The reason is obvious: to avoid adding a new keyword and breaking existing code that might use it as an identifier.


C++ had to add new keywords anyway.


It does, but N new keywords are always going to mean less breakage than N+1 new keywords.

On top of that, the best keywords - e.g. in this case "let" or "var" - are also the ones most likely to clash with identifiers in existing code.


Which if you projected the same syntax to 'let' syntax you get:

let time_keeper = TimeKeeper(Timer());

Which is one less character to type.


> why type var in front of a variable when int x makes it clear its a variable?

Unless `int x` is followed up by an opening parenthesis, in which case it suddenly is a function definition and not a variable. Which also means a parser now needs lookahead for one of the most common statements in the language.

`let` means variable, always. Not only that but in most cases (>90%) you can omit the type as it's obvious. Now you just have to type `let s` instead of `String s`, with the difference that `let` also tells you this variable is immutable, which isn't even possible in many languages in the first place.

> involves typing one more character

Who cares. 99% of devs don't, otherwise they'd use APL or its relatives, where the entire Conway's Game of Life is a single line. There are more important factors than the number of symbols on screen.


In the context of a language that needs to coexist with C++ codebases, it is a weird decision.

However, Carbon's syntax makes technical sense, and is in line with many contemporary languages (Rust, TypeScript, Swift, Kotlin). It is easier to parse, which is important for tooling and IDEs. `fn name` is easy to grep for. `let` works well with type inference and destructuring assignment, which are becoming standard features in modern languages (although Carbon still supports C-style aggregate initializers, which is not so great).


Not every, see Circle.

The only that really has a chance.



Except just like with C++ being a C superset at source code level, Circle is a C++ superset, no need to rewrite existing code, that is the big difference.


Then it's still C++'s syntax, and Circle's syntax is still "ugly". Every modern languages adopt the "ugliness" style of type after name to solve most vexing parse, yet somehow C/C++ programmers are still confident in their "beautiful" syntax.


Syntax being ugly isn't the problem for migration, rather 40 years of history deploying code into production.


That's irrelevant to the discussion about syntax being ugly.


If you add "... in field [x] or application space [y]" to the question it might lead to a useful discussion but as-is the question is too broad.


There needs to be a new PL word for languages that work side-by-side (SxS?) with a legacy language. Not to replace it but coexist peacefully. TypeScript, Kotlin, Swift and even C++ are all great examples of SxS languages.

Carbon could be a great SxS language with enough inertia building up over time: still never aim to replace C++ (a fool’s errand) but always work in conjunction with large C++ codebases.

It’s such a great pleasure to write things in TS while always being able to use mix-match JS libraries and tooling and debugging. I hope Carbon achieves a similar result moving the industry and engineers forward without resorting to “languages are religions” tediousness.


Not really, at least not during this decade.

> Note that we don't expect to finish the 0.1 language work in 2023. Our goal is to make sufficient progress that we can complete it in 2024, but there are still many things that can go wrong and cause significant delays.

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

So while an interesting experiment, and it can even get an ecossytem of its own, provided it doesn't go out of steam, it is still quite far from that.


> Dart is a language on top of JavaScript and other languages with the mission to be the main language for the Flutter project, addressing the creation of cross-platform apps.

The JavaScript part is a factual error. Dart can compile to js. Dart can also soon compile to wasm, but most of dart code runs on the dart VM and has nothing to do with JS.


Suppose you're a big company with a ton of C++ code. You're never going to rewrite it all. It wouldn't even be a good idea.

If only there were a way to write new code in a new language, mostly unconstrained by the long history of C++, but let the two languages share a toolchain, and maintain a logical interface compatibility layer. Not just linking the same ABI, but compatible types, functions, meta-functions (templates), etc.

Then you could implement all of the features and static checks of your dreams, and modify the language and its implementation to make those features/checks more powerful and easy to implement.

My guess is that's the idea. If you weren't a huge company with zillions invested in countless lines of C++, you wouldn't need to consider this. And, regardless, it's a neat idea.


There was a very interesting presentation about how Apple was trying to give Swift a stable ABI that provided forward looking stability.

Apple has a LOT of C/C++/Obj-C/Obj-C++ code. And they certainly have the resources/need for such a thing.

I wonder if what they’re doing could be extended to make integrating new Swift code easier with all the existing non-Swift stuff as it slowly got rewritten.

I’m not suggesting everyone switch to Swift, merely that someone may already be doing something like you’re talking about.


They not only were trying, they made it, it was made stable in Swift 5.


Yeah, but doesn't that approach presume you have a monorepo or something already?

Seems like converting a native python extension to the new language will just break all the downstream users of that package who do not already have the new toolchain set up. That's exactly what happened with the cryptography package when it converted to Rust. And that's just an example. What about all the projects shipping to embedded systems, tiny Linux distros, specialty proprietary OSs, and so on?


There is nothing to replace here. You should only start a new project in C++ if you absolutely have to, and if you really have to, perhaps due to legacy code, then complicating your smoldering dumpsterfire of a build system even more with this stuff is masochistic at best. Meanwhile, that dumpsterfire will burn on for maybe a century and people will have to keep "learning" C++. The only way to make this situation less painful is to finally stop trying to incorporate into C++ every new language that comes out.


The main selling point of Carbon is direct C++ interop, which is extremely rare and makes Carbon unique.


Yes. I believe that doesn't affect my argument. Instead of the ~4 programing languages found within C++20 you would be adding one more to the codebase. Does that sound like a good idea?

Maybe my comment was too harsh. It's great someone's trying to make the C++ situation better. I hope they succeed. I just think they won't and C++ should go the way of C and stop "evolving", while this thing is very similar in spirit to blowing it up even further. (I've actually liked working with C++ for the past 15 years, but not because it's productive but for the stockholmy "challenge" of it)


Being no expert at c++ (far from it..) and knowing nothing about carbon I'd expect that you'd usually need to do at least some cleanup amongst those "~4 languages" (nice way to put it!) on the c++ side before enjoying interop.

But I'd also assume that much (all?) of that cleanup would be stuff that would be worth doing anyways, even if you sticked to c++, but that you keep postponing...


The issue is that it's very hard to "clean C++ up" because backwards compatibility must be upheld (there are obviously good reasons for that). C and C++ have terrible defaults that mostly cannot be changed anymore. You can try to add warnings for everything (people dislike and disable them), static analysis, valgrind, (not trivial to set up and use correctly) etc. etc. You can add new stuff (e.g. smart pointers) and mandate (e.g. C++ core guidelines) that the old ways (new/delete) should not be used. I could continue forever describing measures aimed at making C++ safer.

In my opinion all these things have failed. The language is old, has insane amounts of legacy beurocracy and process tied to it, has terrible unchangeable defaults, unchangeable ABI, and is insanely complicated to "get right" (write a function that adds two signed integers and returns the result, that has no undefined behavior) to the point where there is an established tradition not to try to get it right. Yes, smart pointers are nice, concepts are also nice, but this patchwork does not work well with other features, and what this "improvement" process does is make it more complicated. Almost noone really understands it anymore.

It's time to retire it and start over completely, as well as reconsider if all the things that C++ has been traditionally used for warrant such a language. Things like GC languages or Rust/Zig should fill that space. They have decent interop where needed. Meanwhile C++ is not going away for a very long time. I see this project as building another language into C++ that makes it even more complicated.


Yes, c++ (the language) can't be properly cleaned up because support for not just some but all legacy codebases isn't optional at all. But I wasn't talking about cleaning up c++, the language, I was talking about cleaning up c++ codebases to align them with whatever subset of c++ that will play nice with carbon. Surely won't be everything, whatever obscure leftover from 1984 you dig up, but will likely aling well with good somewhat modern (or modernized) codebases. That would mean ending up with code that cleanup process will likely end up restricting itself to a certain subset of c++ that might in fact be a good candidate for a "somewhat cleaned up c++ language", but I agree, that wouldn't be worth it: a properly different thing designed for interoperability with a large subset of c++ will be much easier to learn than a literal subset.


I just don't believe people will do that. How do you to justify investment in "cleaning up" a huge legacy codebase that noone fully understands anymore, written in a patchwork of programing languages that almost noone really understands anymore, by gradually converting it into a new experimental dialect of said languages that might die a few years down the line?

Javascript -> Typescript is just a different domain, one where things move fast, break and are suddenly replaced or thrown away. This C/C++ stuff is slow. The industry is too big, backwards and fragmented to do anything other than start over with a completely new language where possible, and where it's not possible and just keep cleaning the dust from the antiques and hope.

There's huge C++ projects that should be in e.g. Java if started now (I really dislike Java). On the other hand, there's an ongoing effort (been there for decades!) by a cult-like group of C++ programmers, convincing themselves that they can write memory safe code, and trying to convert embedded C programers and convince them to stop dereferencing volatile hex addresses copied from decades old pdf manuals (e.g. because that's UB). These people still don't use compiler optimizations because who knows what that might do. I've used "modern" embedded C++ and mostly gotten reactions along the lines of "C is better, this new stuff is no good, abstractions obscure stuff, how are we supposed to debug which of those hex adresses don't match the pdf?" What do you do with that? It's not unreasonable: the old way worked well enough, changing things are costly and dangerous.

I believe this mess is not a technology problem that can be solved by adding more language features or dialects to C++.


It certainly depends on how much cleanup a given codebase really needs. But if your only other choices are reimplement everything in rust/java/whatever, never ever touch the core and stick to some FFI scripting layer and never hire anyone who doesn't have at least two decades of c++ on their resume, does carbon really look that unattractive?

What impressed me about carbon (apparently so much that I sound like a embarrassing fanboy even to myself, heh) is how determined they seem in trying to avoid scope creep: usually it's quite the opposite, every field of programming that's not entirely ruled out gets declared home turf that will eventually get revolutionized by the language (because a prototype exists and it looks pretty because it's still in that cute puppy stage when all the gnarly bits are conveniently left out)


I bet that are plenty of dialects in Python 3.11, Java 20, C# 12, C23....

That is what happens when languages stick around for decades


Thing is, C++ really is special in that way. I would say C is at most 2 languages (maybe not even that, or most legacy code is already the "newer" of those), Python is at most 2.5 languages (subtract one because Python 2 is no longer supported in 3). C# and Java have a better shot in this sad competition but still, it's not like you're not supposed to be using 50% of those languages original features anymore.


There are lots of features we are not supposed to use, yet we keep bouncing into them.


The other big selling point is "developer interop". If you work on a stack that is locked to c++ (interop) and need to get developers productive who grew up with the go, rust, kotlin generation of languages, carbon looks extremely promising compared to trying to force-feed them forty years of c++ quirks.


Sadly, if it's interoperable with C++, you'll likely need to know forty years of C++ quirks at some point...

It all just seems like a band-aid (adhesive plaster for non-native speakers).

I wonder if having a stable ABI wouldn't be better. Specifically the CXX project shows how this kind of capability is extremely powerful.


Not really, not when the carbon-only team can throw things back over the wall to the legacy experts who promised proper interop. And that the new devs aren't even tempted to solve it on their own, which would inevitably happen if instead of carbon they'd try to achieve the same by sticking to some modern subset of c++. With carbon, the new generation who don't know better don't have to be painstakingly supervised to not use any bad subsets of those "~4 languages". Saving the man-hours that would otherwise be spent on arguing about the exact composition of that subset would likely be enough to make the switch worthwhile (yeah, I might be projecting, I'd get nothing done at all)


Can't D interop with C++?



from what I recall carbon doesn't have any working interop yet. it's just a feature on the roadmap.


The language is not ready yet, but interop is a core requirement for the project.



The core hypothesis is that for a replacement language to be successful, it cannot only be great for new projects. Besides building on and extending tooling already in wide usage, you want the successor language to interplay elegantly with existing code, affording things like gradual replacement. Of course, that also means that you’re making less of a leap, but considering the vast landscape of active C++ code based, I would put my money behind this successor language argument.


If the idea is to retain the modern features, focus attention on them and peel off all the superseded old stuff then I’m all for it.

Seems to me languages that focus on backward compatibility end up with a great modern core but it kinda gets lost because how do you know that the modern core? Developers learning can’t know what’s new and best and recognize what’s old noise.

It has to be said though that googles reputation for killing projects overshadows anything they do.


As long as we have articles claiming language xyz replaces C++, c++ will be fine. The day none writes about c++ anymore is when it will be replaced.


One thing is that creating a new language is super cool. If I was important enough at Google to get a team for that, I would! And I would be biased when answering questions like "is it really needed?".

That's probably the reason why there is a new language created every second day. Curious to see if one will "win", though.


They keep pointing out Typescript and Kotlin, without understanding that the first only adds type declarations, while the second fakes to be Java at the JVM bytecode level (try javap on a .class generated by kotlinc).

If Carbon ever goes beyond an experiment it will be for Google's own internal purposes.


> while the second fakes to be Java at the JVM bytecode level (try javap on a .class generated by kotlinc)

What's wrong with that? All of my gripes with Java, other than the way they did their generics, are at the language level. The bytecode and underlying VM are works of art. Kotlin adds reification to the JVM and adds explicit nullability annotation as a compile time error rather than a warning, which solves my worst annoyances with Java. I'd still use Kotlin if all it did was transpile itself into .java files and call the compiler for me.


It is the Java Virtual Machine for a reason, the language that gets designed in step with the platform is the one that gets day zero goodies, everyone else plays catch up.

Kotlin also decided to become a platform of its own, just like every guest language.

It is also the reason why despite my C rants, if there is no alternative, that is what I use.

I rather use the tools that ship in the box than adding additional layers to configure and debug.


>without understanding that the first only adds type declarations

https://www.typescriptlang.org/docs/handbook/enums.html



Not forever if this ever comes through,

https://github.com/Jack-Works/proposal-enum


Why would it use let to define a const?


It's not an uncommon choice in modern languages. Rust & Swift both use `let` to mean an immutable binding.


Modern going all the way back to the 1970's in ML, and a common way to declare variables in BASIC.


JS too.


JS has a `let` keyword, but you can reassign the value through it. `let a = 5; a = 6;` is valid JavaScript, and the value of `a` would be 6.


C++ has become a feature magnet and punctuation character gumbo. How long before the Carbon language committee decides they need to add "cool" obscure features found in other languages and thereby needlessly complicate it to death.


Just wait if generic keywords make into Rust, with ? prefixes.


I suppose Betteridge's Law of Headlines provides the answer, but the article doesn't even do a great job of attempting to answer the question.


Low effort TL;DR of the CppNorth presentation to drive traffic to a commercial site.


Dumb question. If you have language servers and AI systems like ChatGPT can’t you train them to rewrite c++ code to a different language? Can’t you also train it to detect pointer errors as well?


It was never heard after announcement. Really doubt anyone need it .


There are many well known problems with C++, not least of which are the long compile times, exception handling, and dependency handling. Anyone who has worked with a sufficiently large C++ code base has run into these issues.

The overwhelmingly negative comments here on HN remind me of the pushback that Rust Linux kernel modules received on HN when they were first announced around 2015/2016. Now they’re seen a much loved feature (I understand they solve different problems so the analogy isn’t perfect). I’m not confident that Carbon can be used to solve the issues that arise in large C++ projects as I’ve never tried it but that’s very different from pretending C++ is some kind of perfect language that doesn’t have these flaws and doesn’t need fixing.


1. Long compile times tend to reflect headers, which are substantially addressable without a new language.

2. exception handling ... meh, i can't take this seriously. There's no ideal exception handling and if this is what is grinding your project to a halt, you've got bigger problems.

3. dependency handling ... if you mean "prepackaged libraries" then I'll repeat again that I don't want solutions to this baked into the language


C++'s compile times are caused by design issues. Dlang compiles nearly instantaneously (for example). Lack of modules, and abiguities in the syntax are roughly what causes it.


I cannot help but wonder if modern language design is a bit like designing better punch card formats in the 70s.

If we can teach AI to program in C/ASM will language features matter?


No


No. Next question, please?


Help improving c++ first please.

then create a profile for whatever Google needs instead.

and also please create a C profile off C++ that is safer than C, and make C a true subset instead of diverging them even further.


Carbon was seemingly borne out of Google’s frustrations that they could not get the C++ committee to agree with their desired improvements and direction for the future.

That is, they’ve already been doing what you ask. Yet here we are.


Specifically, P2137 spells out what key people (not only at Google) wanted and WG21 (the C++ Committee) said "No". Well I mean, as a whole, several of the P2137 authors are WG21 members, this was not a decision made with one unified voice.

https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p21...

Carbon has a few interesting ideas which I hope survive in at least some weird niche languages even if the Carbon experiment fails, because they deserve to be known to people who invent programming languages - some future Rust replacement might find a use for them for example.

But the most important thing Carbon got right that most of these C++ Successor languages did not, was that it understood why Rust is safe. Rust's safety is not primarily about the technology, although of course the technology is important, it's about the Culture, and Carbon understood that.


The next step in software is a language optimized for ai generation. Rust and carbon are for humans and are a side step at best


I love such comments. Humans got here because they are able to solve abstract problems and analitical thinking. Go ahead and pass it all to AI. Whats left? An useless consumer... (go go Skynet :)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: