The Register Home Page

back to article Contracts are in C++26 despite disagreement over their value

The ISO C++ committee (WG21) has approved the C++26 standard, described by committee member Herb Sutter as the most compelling release since C++11, and including Contracts, despite opposition to the feature from C++ inventor Bjarne Stroustrup, among others. The committee met in Croydon, London, and approved the standard on …

  1. Pascal Monett Silver badge

    "help make C++ code safer and more reliable"

    I thought Rust was supposed to be the solution for that.

    Caveat : as far as I know, the only thing more powerful and compact than C++ is Assembly language - in both cases, you want someone who knows what the fuck he's doing.

    1. Anonymous Coward
      Anonymous Coward

      Re: "help make C++ code safer and more reliable"

      > I thought Rust was supposed to be the solution for that.

      Sure, in the same way that Java and .NET are.

      Fragile and dangerous bindings layers unfortunately make it non-viable until they finally bite the bullet and bolt on a tiny C frontend to integrate with the actual computing platform.

      1. FIA Silver badge

        Re: "help make C++ code safer and more reliable"

        Fragile and dangerous bindings layers unfortunately make it non-viable until they finally bite the bullet and bolt on a tiny C frontend to integrate with the actual computing platform.

        What do you mean by this?

        How do you mean 'integrate'?

        It's certanly possible to write code that targets the hardware directly using Rust, no C bindings required.

        1. Anonymous Coward
          Anonymous Coward

          Re: "help make C++ code safer and more reliable"

          Bindings are a known issue. Many resources around to rea.

          Integration is an important aspect of software engineering. Also many resources around to read.

          People need to write software for operating systems not just bare metal. Plus Rust in embedded is so far behind that this is a laughable suggestion.

          With Rust, if you want to target OpenGL, X11, Wayland, Win32, Postgres, etc... you are going to be either maintaining fragile and dangerous bindings against the C API yourself or using some other guys fragile / dangerous bindings.

          Apologies my response is terse, these issues with Rust are not new and have been around for decades since the industry standardized on C, so its a little boring to discuss in 2026.

          1. FIA Silver badge

            Re: "help make C++ code safer and more reliable"

            Bindings are a known issue. Many resources around to rea.

            Integration is an important aspect of software engineering. Also many resources around to read.

            I mean you could quickly link to one to make your point?

            People need to write software for operating systems not just bare metal.

            Yes, both of these are possible in Rust.

            Plus Rust in embedded is so far behind that this is a laughable suggestion.

            Hmmm, embedded stuff in any language isn't great. Lets not pretend C is the poster child for embedded here. Old compilers, old toolchains, etc etc. Plus Rust is a lot younger than C, and is improving rapidly.

            With Rust, if you want to target OpenGL, X11, Wayland, Win32, Postgres, etc... you are going to be either maintaining fragile and dangerous bindings against the C API yourself or using some other guys fragile / dangerous bindings.

            Again, I'd ask for examples. I have two hobby projects on the go in Rust at the moment. One is a Windows app. Which I can target windows and linux on, and with less effort than if I'd used my old favourite cross platform UI library Qt. The other is an operating system. I started writing an OS in C, got to a small multi CPU/multi threaded kernel, then decided to re-write it in Rust (as I'd written a 32 bit kernel and wanted to go 64 bit). Whilst the Rust side of it is still quite new, I've had a much better experience using Rust and it's modern build infrastructure than I had in C. (Christ, not having to customise GCC is a bonus in itself).

            Apologies my response is terse, these issues with Rust are not new and have been around for decades since the industry standardized on C, so its a little boring to discuss in 2026.

            Terseness I don't object to, but I think you might not have the understanding you think you do. Firstly Rust is just over a decade old, so at least give it the chance to catch up with C.

            Secondly, in what way has the industry standardised on C? A lot of Windows is written in C++ or a CLR based language (C# usuall), Linux is largely C, but the industry is much much bigger than these two. Hell the last bit of embedded code I wrote was in pascal of all things.

            Thirdly, and this is the important bit... the inter language bindings are ABI bindings. That is you have to write to the calling convention of the system you're programming for. This dictates what order arguments go on the stack, how return variables are passed, etc etc. Now, it is true that most of these are born out of the initial C compilers and linkers, but they're not 'standard' outside their environments. The calling convention on an ARM is different to x86, and even on x86 there isn't one standard. See here for more info.

            These are the bindings you maintain, you can have the same problems in C if you use differing compilers (GCC and MSVC spring to mind on Windows, although these issues have largely been ironed out), but even in C++ (a close relation to C), you can often end up with judicious __cdecl usage if you're linking externally.

            Also... this article is about C++, which isn't C... and has all the same issues... (or is the 'guy' maintaining the C++ bindings somehow more skilled??)

            1. Anonymous Coward
              Anonymous Coward

              Re: "help make C++ code safer and more reliable"

              > or is the 'guy' maintaining the C++ bindings somehow more skilled??

              C++ is close to a superset of C so can consume C libraries (incl headers) directly. No bindings required. The fact that you needed this clarification means this discussion is not going to be meaningful to either of us.

    2. FIA Silver badge

      Re: "help make C++ code safer and more reliable"

      "help make C++ code safer and more reliable"

      I thought Rust was supposed to be the solution for that.

      Rust is more like C, not C++, it's not OO.

      It's not a replacement to anything, but it can be an alternative if it suites the use case. (e.g. a greenfield project is probably better in a more modern language if you have the skillset available).

      (Aside: Well done! You got 'Rust' into the first comment about an unrelated language, that's 2 shots on 'The Reg' drinking game, I'm going to be banjaxed by the end of this comment thread).

    3. kmorwath Silver badge

      Re: "help make C++ code safer and more reliable"

      Rust is not object oriented, and has no exceptions. It's not a replacement for C++ and other OO languages, it's a replacement for C.

  2. Locomotion69 Bronze badge

    Contracts, as used in Eiffel, or D, or Ada.

    I cannot see how an attempt to have a formal approach to be specific on behavior for pieces of code can be a "bad thing".

    You do not have to use it - but I can see some fields in where contracts are welcome!

    1. that one in the corner Silver badge

      It is my understanding that the issues are with the implementation, not the concept of contracts: putting it into the rest of C++, including sticking to the promise that, if you choose not to use it, your code does not pay a penalty. Even if some of the code you drag in from a third-party decides to use it*.

      assert() is the greatest thing in K&R and every improvement on that is (should be!) a joy.

      * even the old point about whether you need to add a compiler flag to support dynamic_cast<> everywhere can be more than a minor niggle

    2. Alan Mackenzie

      Myth: "You don't have to use it"

      > You do not have to use it - but I can see some fields in where contracts are welcome!

      You are forced to "use" it when the person whose code you're fixing has used it. "You don't have to use it" is as insidious as "I have nothing to hide".

  3. munnoch Silver badge

    Virtual functions

    Lack of support for virtual functions makes this much less useful than if could be. Yeah, I know, I'm old fashioned and like my polymorphism.

    I was (2 years retired) a very enthusiastic user of the assert macro with pretty much the same intent as this extension. Pre/post and inline predicates that should always hold. Absolutely invaluable in making your assumptions explicit and executable. "Don't call this function unless you can provide parameters in this shape". "After you call me I promise the following will hold".

    Co-workers hated me for rubbing their noses in their laziness and stupidity. The number of times I've had a an email begging to be allowed to remove an assertion so that their code can "work". Some would just go ahead and remove an assertion as part of a PR without even bothering to ask. The entire concept of correctness seems to be lost on many programmers.

    Problem of course is when the assertion turns out to be wrong or too strict and a case is discovered that brings everything to a screeching halt. The standard does seem to have considered that with ability to handle failures or ignore evaluation. Devil is in the details...

    1. Bebu sa Ware Silver badge
      Facepalm

      Re: Virtual functions

      "The entire concept of correctness seems to be lost on many programmers."

      Honestly I don't think that many ever had even the most tenuous grasp of the concept to be able to lose it. Some developers' demonstrate an equally tenuous acquaintance with sanity or indeed reality.

      I would be surprised if very many contemporary software engineering syllabi deal with programming language semantics at all, let alone weakest precondition semantics which "contracts" presumably mirrors.

      Often the problem is deeper still, in that the specification handed to developers even when unusually well defined, is frequently internally (logically) inconsistent and always incomplete. The latter hands the developers a bucket of undefined states from which well defined state are expected to deterministically proceed, and augments the former declarative inconsistencies to produce the usual unholy logical shambles.

      1. that one in the corner Silver badge

        Re: Virtual functions

        > I would be surprised if very many contemporary software engineering syllabi deal with programming language semantics at all, let alone weakest precondition semantics which "contracts" presumably mirrors.

        Ask them to justify their "loop invariant" and watch the eyes: "rabbit in the headlights" or glazed incomprehension, bad. All too common, but bad.

        1. Someone Else Silver badge

          Re: Virtual functions

          "Well heck!", exclaimed the recently sheepskinned entry-level applicant. "We don't have to worry about loop invariants; what with Moore's Law and compiler optimization, loop invariants are soooo 20th century!"

          Manager: You're hired!

      2. sarusa Silver badge
        Devil

        Re: Virtual functions

        > The entire concept of correctness seems to be lost on many programmers.

        That's okay, because it's 100% lost on vibe coding tools and that's what everyone's using now. The idea of correctness is dead. You get Windows 11 instead.

        1. You aint sin me, roit

          Re: Virtual functions

          Also: "If someone finds the problem we'll provide a fix in the next patch"

    2. Anonymous Coward
      Anonymous Coward

      Re: Virtual functions

      > The number of times I've had a an email begging to be allowed to remove an assertion so that their code can "work".

      Email? You got an email?

      I got pressured to cut a recuperative hospital stay short to be in the next day to fix the message that my library was throwing and nobody could understand.

      I was not best pleased to find it was an assert() firing and nobody had even been able to say that on the phone call (yes, the message that starts "assert failure at..." Not deep in the library, no, it was from the public API. Where matey had put in a C-style cast to make it compile!

      I did not stay there.

      1. Eclectic Man Silver badge
        Facepalm

        Re: Virtual functions

        I'm sure a great deal of commentators on the Register hope you recovered well from both your stay in hospital, and that employment.

        I recall a former colleague had a very bad time in his mid 40's, had no idea what was wrong with him but he could not digest anything very much, Hospitalised, he was diagnosed with lactose intolerance. While recovering (in hospital) the Managing Director visited him, taking some work for him to do, 'if he wanted to '. On his return to work he would have herbal teas. We took turns making a round of drinks, the Chairman (it was a small company approx 8 people) would forget, and put milk in everyones' drinks ... (Nope, that company did not end well, either.)

    3. Roland6 Silver badge

      Re: Virtual functions

      >” Problem of course is when the assertion turns out to be wrong or too strict and a case is discovered that brings everything to a screeching halt.”

      There is the other problem - common to some branches of computing - you do not want your program to come to a screaming halt: either the exception needs to be handled or the system needs to enter a controlled shutdown ie. Fail safe.

    4. Someone Else Silver badge
      Facepalm

      Re: Virtual functions

      The entire concept of correctness seems to be lost on many programmers.

      That would be the inevitable result of valuing "completing the PR" over "providing working code". And that is the inevitable result of valuing "meeting a deadline" over "providing a working product".

      And that, kids, is how enshittification happens in today's software "industry".

  4. Bebu sa Ware Silver badge
    Facepalm

    Stroustrup said ... I worry a lot about the complexity

    as well he might.

    C++ has become another "estabilished" church as byzantine as any actual faith or the rituals of Gormenghast.

    Rookie C++ developer meets AI coding assistant should blaze new trails of heretofore undreamt of buggery.

    As a previously noted Eiffel had this as foundational feature and is arguably a much simpler language than any C++ spec since the C++ ARM.

    1. Rich 2 Silver badge

      Re: Stroustrup said ... I worry a lot about the complexity

      The complexity is why I have really gone off C++

      I have a sort of very extensive reference manual that I wrote for C++ - it’s on the web - I stopped updating it shortly after adding some C++20 changes

      I think the nail in the coffin for me was looking at the C++ 20 implementation of coroutines. I made a note at the time in my manual…

      “The standard C++20 coroutine implementation is probably the ugliest, clunkiest, most needlessly complicated and badly conceived implementation imaginable. It should be consigned to the dustbin of software atrocities, and we should all try to forget it ever existed “

      I fully stand by that assessment today

    2. frooks-falt-pyramid

      Re: Stroustrup said ... I worry a lot about the complexity

      Have an upvote for "undreamt of buggery".

    3. Chris Gray 1

      Re: Stroustrup said ... I worry a lot about the complexity

      Have an upvote for Gormanghast. I tried, I really tried, to read that. Gave up somewhere in volume 2.

      1. Rich 2 Silver badge

        Re: Stroustrup said ... I worry a lot about the complexity

        I’ve not read it myself but I’ve heard from others that it’s tough going.

        The most impenetrable book I ever tried to read was “The coming of the king” by Nikolai Tolstoy. I think I made it to chapter 3. Maybe 2 (hint - unless you are fluent in Welsh - at least that’s what I think it was (old Cornish maybe?) - then forget it)

    4. martinusher Silver badge

      Re: Stroustrup said ... I worry a lot about the complexity

      The reason why I shy away from this type of complexity is the default solution to any and every problem seems to be 'terminate the program with maybe an understandable error message if you're lucky'. I've spent most of my working life in the embedded world where the one thing you cannot do is just terminate a program, the thing has to keep operating (and if a shutdown is needed then it has to be an orderly shutdown or transition to a designed safe state). What this translates to in practice is that the normal function of a program is really only part of the overall design, in fact it might be quite a small part.

      Software for humans should follow the same design principles but it doesn't because (I suppose) its just too much work. Especially as understanding and designing for error conditions not only has to be coded for but also tested -- the fact that a program appears to work doesn't mean its working.

  5. karlkarl

    I presented my safety solution (C++/sys) at C++Online 2026 recently (https://cpponline.uk/session/2026/cpp-sys/)

    Through this, there was lots of discussion about contracts. It is exciting but I am not too sure about their applicability just yet. The extra work required to benefit from them feels a little fussy and verbose. This might restrict their use when what we need is essentially full coverage within a codebase.

    But it does give us the hooks required to automate some of it.

  6. that one in the corner Silver badge

    Play the ostrich

    As I no longer have to look at other people's efforts, I shall happily continue to write C++ code using only the bits that I understand* and can draw out a quick low-level "what it looks like in memory" diagram.

    Including a note on which loops can allocate memory (hint: not during any inner loops that are chewing numbers, looking at certain people whose insistence that four levels of nested templates and a few "auto" declarations are better than any typedef).

    * which does still increase over time, although these days the time balance between reading about the latest "modern C++" versus getting the blinkies to actually do useful work within the constraints of the microcontroller tends towards the latter. Static reflection sounds interesting... scroll, scroll, past the list of document changes...

  7. trevorde Silver badge

    Design by committee

    Like the proverbial camel, why do they keep adding features to the language? It just adds complexity, increases the learning curve and adds marginal value. My favourite language, C#, has changed beyond all recognition, and not for the better.

    1. Alan Mackenzie
      FAIL

      The different C++ languages

      And here we go again, a new C++ standard yet more complicated than its predecessors. It has long reached a stage where the language is too complicated for any but a few to learn thoroughly. So each user learns but a subset of the language.

      The problem is, that different users learn different subsets, even if subtly so. So a large C++ program (are there any others?) is programmed in many different languages. That can't generate an expectation of a reliable efficient program.

      1. Anonymous Coward
        Anonymous Coward

        Re: The different C++ languages

        But at least it is fully defined, unlike Rust…

        1. FIA Silver badge

          Re: The different C++ languages

          How big is a 'char' in C++?

          1. that one in the corner Silver badge

            Re: The different C++ languages

            > How big is a 'char' in C++?

            That is fully defined by "look it up in your compiler manual" and "taking into account your target architecture" :-) As it should be (see also "what size is a pointer in C?")

            OR as it has been with C, by rapping you over the knuckles for not using the int16_t etc types, which *are* all well defined.

            1. You aint sin me, roit

              Re: The different C++ languages

              Also, I imagine most programmers don't really care (whether they should or not is a different question - does it really matter if you have a few gig of RAM?).

              Those who need to know will make it their business to know the platform they are targeting.

      2. Taliesinawen

        Re: The different C++ languages

        > .. So a large C++ program (are there any others?) is programmed in many different languages ..

        Haa yea, depending on the idiosyncrasies of the programmer, each C++ program is written in its own language :|

    2. coconuthead

      Re: Design by committee

      They keep adding features because it advances some peoples’ careers to do so. The same has been happening with several other languages as the industry just kept hiring more and more developers that couldn’t all be used to solve their employers’ actual business problems. And so we got this framework, and that build system, and the other needless architectural redesign – and language extensions. That the C++ “committee” has 240 members should be a clue that something’s very wrong; but of course no-one wants to step away because being on the committee brings kudos and travel. Being an ISO process, there’s no benevolent dictator like van Rossum used to be for Python, to say “no”.

  8. Dinanziame Silver badge
    Windows

    I was quite old when I realized

    that Stroustrup was in fact a real person and not a fictional character named after a string function

  9. Anonymous Coward
    Anonymous Coward

    Making it Work for Real

    Marginal Gains

    Contracts seems like a good thing. But projects that don't care about rigour and correctness still won't use them. If they're not already diligently checking function inputs and returns against a bunch of asserts or similar. then they're not going to write contracts either. Probably, there's no real world benefits arising from them. They might make diligent folks' code look neater going forward, but there wasn't really anything wrong with some well written asserts in the first place.

    There's only value in some safety measure such as contracts if the compiler can be told to enforce it. If we're lucky, there'll be compiler switches. What would be better - a whole lot better - if there were some sort of mark-up in the code to say, "contracts should be defined, error if they're missing". Keywords are better because then the whole intent is in one place, and not split between code and build system. If what they've done with contracts is to make them optional, with no way to globally enforce their existence across a code base, its not actually going to help existing code bases.

    Behind the Curve

    The pity is that the idea of interface contracts has in itself been around for a long time, at least since the 1980s. For C++ to consider itself to be "modernising" by adopting them in 2026 is somewhat farcical. When one considers that there has for quite a long time now been things like JSON schemas that can be used to define and enforce interfaces in the chaos-strewn world of Javascript, C++ only just getting round to thinking about the concept is not cutting edge, clever or something to be pleased about. And when one looks at how the telephony industry has done interface specification and enforcement since the very early 1990s using ASN.1 schemas and tools (and ASN.1 makes an appearance in Erlang), C++ at least 30 years behind the curve.

    Dodging Fundamental Issues

    Overall, it feels like more rearranging of the deck chairs on the Titanic++. The consequence is that whilst the C++ standards bodies / persons keep tinkering with making code look pretty whilst not actually fundamentally improving the language, they're conning folk into sticking with the language against their best interests and against the strong advice of really quite a lot of very important people who know what they're talking about.

    And oh! how slow the progress. They've bumped memory safety off to at least 2029, SOME 17 YEARS after the concept first arose in Rust (which demonstrated that one does not need runtime environments and garbage collector threads to do memory safety) and 30 years after Java (which introduced the idea of "you don't have to care so much about memory" in a compiled language). Instead, what we get is the removal of undefined behaviour for reading uninitialised variables being touted as a "better memory safety" feature.

    If this language is going to continue to fall behind the curve, the funding bodies should stop funding them. It's a waste of money, and it's muddying the waters on where existing projects should look to for their future.

    1. Alan Mackenzie
      Holmes

      Garbage collection: [Making it Work for Real]

      > .... and 30 years after Java (which introduced the idea of "you don't have to care so much about memory" in a compiled language).

      Actually the idea of garbage collection was first implemented more like 70 years ago in Lisp, which has been a compiled language for most of that time.

    2. david 12 Silver badge

      Re: Making it Work for Real

      I see that you haven't realized that Dartmouth BASIC was a compiled language.

      For myself, I fail to see how any concepts RUST introduced about memory safety were new to anyone other than c programmers. So perhaps I have my blind spots too.

    3. Richard 12 Silver badge

      Re: Making it Work for Real

      C++ has had memory safety since RAII and xxx_cast<>

      Contracts are about functional safety, a feature that ADA had many, many years ago. In general I'm in favour, but the details really matter.

      Sadly, I agree with Stroustrup.

      The only options are "ignore", "diagnostic", std::terminate(), std::abort() or "instant kill".

      That means a contract failure is either ignored, ends the program with no chance of recovery, or ends the program with no chance of even logging that it happened.

      So it's not a replacement for assert(), as that is known to always std::abort() and so could be hooked to report the error in application-defined ways.

      On the gripping hand, it is a start and can be changed in 2029 with a few years of experience of it not being used "because y".

      1. bazza Silver badge

        Re: Making it Work for Real

        >The only options are "ignore", "diagnostic", std::terminate(), std::abort() or "instant kill".

        >That means a contract failure is either ignored, ends the program with no chance of recovery, or ends the program with no chance of even logging that it happened.

        That's unhelpful for programs that have to achieve some sort of runtime resiliency to error. Not everything can run in a disposable container...

      2. Anonymous Coward
        Anonymous Coward

        Re: Making it Work for Real

        >C++ has had memory safety since RAII and xxx_cast<>

        But it still has all the other features that are not memory safe.

        Personally speaking I quite like C++, but it's getting increasingly difficult to justify new projects in it. The group that steers the evolution of the language aren't doing anything to address that - not until at least 2029. And unless existing or new projects are written entirely in a particular style (which means continuing review burden), or something very clever happens, the tech debt continues to accumulate with no clear idea as to whether changes to the language will ever come to the rescue and replace review effort with compiler error messages. Other languages are "Jam today, and jam tomorrow". C++ is dangling "jam tomorrow" as some sort of far off distant dream whilst not really telling anyone which of the current range of language ingredients available today may or may not be a part of tomorrow's jam.

        Basically, please just decide already...

        There's nothing wrong with C++ choosing in either direction. If C++ were to remain as it is - no guaranteed memory safety where a programmer can if they want take some real liberties and you have to review the code really, really carefully - fine, it'll have continued and new uses, selected on its merits. If C++ were to offer a compulsory memory safety mode where the compiler is pointing out your every mistake, also fine. Being stuck in the middle helps no one.

  10. Groo The Wanderer - A Canuck Silver badge

    'The paper [PDF] describing Contracts for C++26 notes that "behind the attempts to add a Contracts feature to C++ is a long and storied history." Contracts were also part of the C++20 working draft but WG21 removed them in 2019 following major changes in the proposed design.'

    In other words they've argued about it interminably and have never managed to convince Mr. Stroustrap of the benefits, but being a bureaucratic organization, and a standards organization notorious for over-documenting every single nit-picking detail you never thought of no less, has decided in their infinite "wisdom" that "more complexity for the compiler writers is clearly better for the reliability and performance of the code; we'll just leave all the heavy lifting 'up to the implementation details.' *muahahahahaha*"

  11. petef

    /me dusts down copy of Object-Oriented Software Construction.

  12. rivergarden

    C++ has gone downhill...

    "The committee met in Croydon, London"

POST COMMENT House rules

Not a member of The Register? Create a new account here.

  • Enter your comment

  • Add an icon

Anonymous cowards cannot choose their icon