C++26 is done: ISO C++ standards meeting Trip Report (herbsutter.com)

by pjmlp 425 comments 314 points
Read article View on HN

425 comments

[−] suby 47d ago
I am somewhat dismayed that contracts were accepted. It feels like piling on ever more complexity to a language which has already surpassed its complexity budget, and given that the feature comes with its own set of footguns I'm not sure that it is justified.

Here's a quote from Bjarne,

> So go back about one year, and we could vote about it before it got into the standard, and some of us voted no. Now we have a much harder problem. This is part of the standard proposal. Do we vote against the standard because there is a feature we think is bad? Because I think this one is bad. And that is a much harder problem. People vote yes because they think: "Oh we are getting a lot of good things out of this.", and they are right. We are also getting a lot of complexity and a lot of bad things. And this proposal, in my opinion is bloated committee design and also incomplete.

[−] WalterBright 47d ago
I implemented Contracts in the C++ language in the early 90's as an extension.

Nobody wanted it.

https://www.digitalmars.com/ctg/contract.html

[−] Twey 46d ago
I think it's also true that, regardless of the desirability of the feature at the time (which sibling comments discuss eloquently) people who've bought into a language are usually quite wary of also buying into extensions to that language. The very act of ratification by the committee gives this proposal a ‘feature’ that the DMC++ extension lacked in compatibility expectations over time and across implementations — it's not necessarily a comment on the technical quality or desirability of the work itself.
[−] Defletter 46d ago
But then why did you add your contract system to D? You implemented your contract system in the "early 90's", and D was released in 2001, so that's near a decade of "nobody wanted it". So then why add them as a core language feature of a new programming language if no one wanted it? Why is it still a core language feature? And why object to C++ finally adding contracts. I just don't get what you're even arguing here.
[−] WalterBright 45d ago
It's a great question! I simply had faith that it was a good idea.

The reason I started D in the first place is the C++ community was uninterested in any of my ideas for improvement. Ironically, C++ would up adopting a lot of them one by one! Such as contracts!

Contracts did find an enthusiastic constituency in the D community.

[−] mort96 47d ago
How do you know nobody wanted it?
[−] ChrisGreenHeur 47d ago
it could be possible that llms can mak great use of them
[−] locknitpicker 47d ago

> Nobody wanted it.

The fact that the C++ standard community has been working on Contracts for nearly a decade is something that by itself automatically refutes your claim.

I understand you want to self-promote, but there is no need to do it at the expense of others. I mean, might it be that your implementation sucked?

[−] addaon 47d ago
I can’t speak to the C++ contract design — it’s possible bad choices were made. But contracts in general are absolutely exactly what C++ needs for the next step of its evolution. Programming languages used for correct-by-design software (Ada, C++, Rust) need to enable deep integration with proof assistants to allow showing arbitrary properties statically instead of via testing, and contracts are /the/ key part of that — see e.g. Ada Spark.
[−] jandrewrogers 47d ago
C++ contracts standardizes what people already do in C++. Where is the complexity in that? It removes the need to write your own implementation because the language provides a standard interoperable one.

An argument can be made that C++26 features like reflection add complexity but I don't follow that argument for contracts.

[−] randusername 46d ago

> It feels like piling on ever more complexity to a language which has already surpassed its complexity budget, and given that the feature comes with its own set of footguns I'm not sure that it is justified.

This is a common sentiment about C++, but I find it very interesting that everyone seems to have a different feature in mind when they say it.

[−] locknitpicker 47d ago

> I am somewhat dismayed that contracts were accepted. It feels like piling on ever more complexity to a language which has already surpassed its complexity budget, and given that the feature comes with its own set of footguns I'm not sure that it is justified.

I don't think this opinion is well informed. Contracts are a killer feature that allows implementing static code analysis that covers error handling and verifiable correct state. This comes for free in components you consume in your code.

https://herbsutter.com/2018/07/02/trip-report-summer-iso-c-s...

Asserting that no one wants their code to correctly handle errors is a bold claim.

[−] ghighi7878 47d ago
Just because Bjarne thinks the feature is bad doesnt mean it is bad. He can be wrong. The point is, most peoppe disagree with him, and so a lot of peoppe do think it is good.
[−] zzzoom 47d ago
That's a genius idea, keep adding broken stuff into the standard until there's no choice but to break compatibility to fix it.
[−] devnullbrain 47d ago
[−] DenisM 47d ago

>to a language which has already surpassed its complexity budget

I've been thinking that way for many years now, but clearly I've been wrong. Perhaps C++ is the one language to which the issue of excess complexity does not apply.

[−] btown 46d ago
Is there any good documentation about contracts? https://en.cppreference.com/w/cpp/language/contracts.html is incredibly confusing - its first displayed example seems to be an edge case where the assertion itself causes a mutation?

https://en.cppreference.com/w/cpp/language/function.html#Fun... is vaguely better, but still quite dense.

IMO the syntax makes things hard for a newcomer to the syntax to understand, which I see as core to any programming language's goals of community.

    double square_root(double num) asserts_pre(num >= 0)
would have been far more self-evident than just

    double square_root(double num) pre(num >= 0)
But I suppose brevity won out.
[−] mort96 47d ago
Contracts are already informally a thing: most functions have preconditions, and if you break those preconditions, the function doesn't make any guarantees of what it does.

We already have some primitive ways to define preconditions, notably the assert macro and the 'restrict' qualifier.

I don't mind a more structured way to define preconditions which can automatically serve as both documentation and debug invariant checks. Though you could argue that a simpler approach would be to "standardize" a convention to use assert() more liberally in the beginning of functions as precondition checks; that a sequence of 'assert's before non-'assert' code should semantically be treated as the functions preconditions by documentation generators etc.

I haven't looked too deep into the design of the actual final contracts feature, maybe it's bad for reasons which have nothing to do with the fundamental idea.

[−] armchairhacker 47d ago
I wonder if C++ already has so much complexity, that it would actually be a good idea to ignore feature creep, and implement any feature with even the most remote use-case.

It sounds (and probably is) insane. But if a feature breaks backwards compatibility, or can't be implemented in a way that non-negligibly affects compiler/IDE performance for codebases that ignore it, what's the issue? Specifically, what significant new issues would it cause that C++’s existing bloat hasn’t?

C++20 isn't fully implemented in any one compiler (https://en.cppreference.com/w/cpp/compiler_support.html#C.2B...).

[−] troupo 47d ago

> So go back about one year, and we could vote about it before it got into the standard, and some of us voted no. Now we have a much harder problem. This is part of the standard proposal.

Offtopic, but this is a problem in the web world, too. Once something is on a standards track, there are almost mechanisms to vote "no, this is bad, we don't need this". The only way is to "champion" a proposal and add fixes to it until people are somewhat reasonably happy and a consensus is reached. (see https://x.com/Rich_Harris/status/1841605646128460111)

[−] DrBazza 46d ago
C++ isn't the first language to do things, but was/is often the first mainstream language to do things.

And then people complain about C++ for doing it wrong, or its complexity, and show language 'X' that does it better/right, but only because they saw C++ do it first, and 'not quite right'.

I expect contracts to be similar - other languages will watch, learn, and do version two, and then complain about c++, etc.

It took 'quite a while' to get rid of auto_ptr, for example.

If it wasn't for the fact this is a language feature, it would be better off in boost where it can be tested in the wild.

[−] seertaak 47d ago
Can you share what aspects of the design you (and Stroustroup) aren't happy with? Stroustroup has a tendency of being proven right, with 1-3 decade lag.
[−] raincole 47d ago
I mean... it's C++. The complexity budget is like the US government's debt ceiling.
[−] Waterluvian 47d ago
Has any project ever tried to quantify a “complexity budget” and stick to it?

I’m fascinated by the concept of deciding how much complexity (to a human) a feature has. And then the political process of deciding what to remove when everyone agrees something new needs to be accepted.

[−] raverbashing 47d ago
Geez if Bjarne thinks it's

> bloated committee design and also incomplete

That's truly in that backdoor alley catching fire

[−] Maxatar 47d ago
Without a significant amount of needed context that quote just sounds like some awkward rambling.

Also almost every feature added to C++ adds a great deal of complexity, everything from modules, concepts, ranges, coroutines... I mean it's been 6 years since these have been standardized and all the main compilers still have major issues in terms of bugs and quality of implementation issues.

I can hardly think of any major feature added to the language that didn't introduce a great deal of footguns, unintended consequences, significant compilation performance issues... to single out contracts is unusual to say the least.

[−] jcalvinowens 47d ago
The "erroneous behavior" redefinition for reads of uninitialized variables is really interesting: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p27...

It does have a runtime cost. There's an attribute to force undefined behavior on read again and avoid the cost:

    int x [[indeterminate]];
    std::cin >> x;
[−] LatencyKills 47d ago
This is awesome. I've was a dev on the C++ team at MS in the 90s and was sure that RTTI was the closest the language would ever get to having a true reflection system.
[−] dataflow 47d ago

> Second, conforming compiler and standard library implementations are coming quickly. Throughout the development of C++26, at any given point both GCC and Clang had already implemented two-thirds of C++26 features. Today, GCC already has reflection and contracts merged in trunk, awaiting release.

How far is Clang on reflection and contracts?

[−] mohamedkoubaa 47d ago
Biggest open question is whether the small changes to the module system in this standard will actually lead to more widespread adoption
[−] vr46 47d ago
Hosting the meeting in Croydon and not letting people leave until the thing is signed-off is definitely a cunning strategy. Never want to work down there again, ever.
[−] einpoklum 47d ago
If you ask me (and why wouldn't you? :-)...) I really wish the C++ WG would do several things:

1. Standardize a restrict keyword and semantics for it (tricky for struct/class fields, but should be done).

2. Uniform Function Call Syntax! That is, make the syntax obj.f(arg) mean simply f(obj, arg) . That would make my life much easier, both as a user of classes and as their author. In my library authoring work particularly. And while we're at it, let us us a class' name as a namespace for static methods, so that Obj::f the static method is simply the method f in namespace Obj.

3. Get compiler makers to have an ABI break, so that we can do things like passing wrapped values in registers rather than going through memory. See: https://stackoverflow.com/q/58339165/1593077

4. Get rid of the current allocators in the standard library, which are type-specific (ridiculous) and return pointers rather than regions of memory. And speaking of memory regions (i.e. with address and size but no element type) - that should be standardized too.

[−] VerifiedReports 47d ago
As long as programmers still have to deal with header files, all of this is lipstick on a pig.
[−] porise 47d ago
I don't care until they stop pretending Unicode doesn't exist.
[−] affenape 47d ago
Finally, reflection has arrived, five years after I last touched a line in c++. I wonder how long would it take the committee, if ever, to introduce destructing move.