I get as exasperated at C++ as anyone else, but IMO there's another takeaway here, which is that smart contracts are an absolutely terrible idea. Relying on code as the source of truth for a transaction just completely disregards the reality that code is always going to be buggy. For those who might not be aware, this is the same smart contract framework where someone accidentally killed $300 million of transactions because a function in a library for setting the wallet associated with a private key was defined as public instead of private: https://medium.com/cybermiles/i-accidentally-killed-it-and-e...
Yes, you can fix issues like this with a "hard fork" if you have a large enough consensus, but at that point, does the system of having smart contracts actually improve anything over the one where the software is downstream rather than the source of truth, or are you just replacing one form of "human intervention required" with a different but worse one?
It's about a compiler bug in C++ that had downstream effects in the compiler for Solidity, which is a language for developing smart contracts. Yes, every compiler can have bugs, even ones not relating to smart contracts, but that doesn't seem like a very convincing argument that we should be using compilers for more things rather than boring regular code that isn't considered to be contractual.
Does it fix them only going forward, or does it actually update what happened in previous transactions retroactively? If the latter, does everyone involved with any transactions using the said contract have a say in whether the upgrade occurs? I'm skeptical that this would actually be a good mechanism in general given how likely it seems that some contracts might be so widely used to essentially require a hard fork in order to upgrade retroactively, but I'm open to the idea that I might be missing something here.
It only updates the code that will run. Fixing it going forward. To protect oneself against losses due to bugs people can use insurance smart contracts.
It's not slightly, it's substantially more complicated to become substantially more convenient. The leap from C to C++ is similar to the leap from assembly code to C. As you add features, the language becomes more complex. That's just how it is.
Most languages deal with this by limiting the features they have - but not C++! (or Scala, which is like Java's C++)
This is a perfect summary of C++: substantially more complicated for substantial convenience.
Add Boost to the mix, as in this bug, and C++ becomes quite ludicrous really, but it can also combine efficiency, interoperability, and performance in a way that's quite difficult to achieve in other languages.
IMO, starting a good C++ project is an exercise in defining a specific language based on a subset of C++ more than anything else: done right, it can be a big lever, done wrong, it can be a big foot-gun.
If we make the underlying mistake in Rust (actually I did last week for unrelated code) by defining an operator implementation as simply calling itself rather than calling some concrete implementation, the compiler warns us, this is infinite recursion which probably wasn't what you wanted.
G++ has to emit code here to recurse infinitely, so it's not as though there's no opportunity to say "Huh, that probably won't be what they meant"
Fair. That's actually crazy - I dug into this more and found the chosen Boost package fails tests on the chosen compiler, and so if they'd done even a cursory check to see if what they're doing could make sense there'd be red flags everywhere.
So the overall story is mostly "Our QA is garbage".
You don't have to use all the fancy new features though. Personally I just stick to C++98 for the most part, unless I really want to use auto or lambdas for some reason, then I might use 11, but I won't go higher.
C++ 11 with lambdas is so much nicer than 98, but even if 14, 17, 20 and 23 have been minor in comparison the accumulated changes have been radical in making what was introduced in 11 into something really useful.
Making anything remotely useful out of templates was deeply into hideous SFINAE-land (substitution-failure-is-not-an-error) leading to horrible unreadable templates during 98 (and the variable-number templates in 11 while being useful only made it explode in horrendeous hacks).
"if constexpr" from C++ 17 and forward actually makes template-expansions not too horrid. you can do template expansions that reads mostly like regular if-elseif-else clauses (and I think that was perhaps part of the impetus for Zig's comptime, starting from this point with a clean slate instead of going through regular template evolution hell).
The horrendous hacks went away with concepts. SFINAE is dead. Spaceship operator, while perhaps not ideal from every perspective, radically simplifies the workload of implementing comparators.
Scala has the advantage (and disadvantage) of not caring one lick about backwards compatibility. They were perfectly happy to burn it all to the ground and redo the language's syntax in v3. And even point releases of Scala frequently have breaking changes.
The better question, in my opinion, is how many other known defects are just sitting there in the GNU buganizer with good reports for more than a decade.
Okay, but why
on 6 lines of trivial example code? Of all the things to make proprietary...More importantly, it’s apparently non-conforming: https://opensource.stackexchange.com/a/12412
Other than that, simply not specifying any license would be equivalent.
Would the license help to prevent an AI training on the example code?
If they eventually start paying attention to licenses, maybe?
No, AI companies are apparently exempted from copyright laws.
I saw that too and had to double take lol
All I took away from this is how more and more complicated C++ as a language becomes to make the syntax slightly more convenient.
I get as exasperated at C++ as anyone else, but IMO there's another takeaway here, which is that smart contracts are an absolutely terrible idea. Relying on code as the source of truth for a transaction just completely disregards the reality that code is always going to be buggy. For those who might not be aware, this is the same smart contract framework where someone accidentally killed $300 million of transactions because a function in a library for setting the wallet associated with a private key was defined as public instead of private: https://medium.com/cybermiles/i-accidentally-killed-it-and-e...
Yes, you can fix issues like this with a "hard fork" if you have a large enough consensus, but at that point, does the system of having smart contracts actually improve anything over the one where the software is downstream rather than the source of truth, or are you just replacing one form of "human intervention required" with a different but worse one?
As opposed to being subject to interpretation of the truth, with the courts of varying quality. My point is... everything has error bars.
This is about a language compiler bug. There are no takeaways about smart contracts here.
It's about a compiler bug in C++ that had downstream effects in the compiler for Solidity, which is a language for developing smart contracts. Yes, every compiler can have bugs, even ones not relating to smart contracts, but that doesn't seem like a very convincing argument that we should be using compilers for more things rather than boring regular code that isn't considered to be contractual.
So long as you’re writing your smart contracts with a chisel, into a stone tablet, with no compilers or assemblers in sight!
You can fix smart contracts without a hard fork. In fact it's common practice for them to be upgradable.
Does it fix them only going forward, or does it actually update what happened in previous transactions retroactively? If the latter, does everyone involved with any transactions using the said contract have a say in whether the upgrade occurs? I'm skeptical that this would actually be a good mechanism in general given how likely it seems that some contracts might be so widely used to essentially require a hard fork in order to upgrade retroactively, but I'm open to the idea that I might be missing something here.
It only updates the code that will run. Fixing it going forward. To protect oneself against losses due to bugs people can use insurance smart contracts.
It’s less about convenient syntax and more about simplifying the construction of abstractions.
You could argue that the latter is the core drive to evolve the standard.
Every new version of C++ (and sometimes even new versions of C++ compilers) can break code in subtle ways.
You should always do extensive testing before upgrading.
That’s the crux of the issue. People fear upgrading because of the bugs introduced by more complexity for more terse syntax.
How much longer will you suffer?
The same is true for any software. If you care about reliability, you pin, and carefully test before upgrading.
It's not slightly, it's substantially more complicated to become substantially more convenient. The leap from C to C++ is similar to the leap from assembly code to C. As you add features, the language becomes more complex. That's just how it is.
Most languages deal with this by limiting the features they have - but not C++! (or Scala, which is like Java's C++)
This is a perfect summary of C++: substantially more complicated for substantial convenience.
Add Boost to the mix, as in this bug, and C++ becomes quite ludicrous really, but it can also combine efficiency, interoperability, and performance in a way that's quite difficult to achieve in other languages.
IMO, starting a good C++ project is an exercise in defining a specific language based on a subset of C++ more than anything else: done right, it can be a big lever, done wrong, it can be a big foot-gun.
If we make the underlying mistake in Rust (actually I did last week for unrelated code) by defining an operator implementation as simply calling itself rather than calling some concrete implementation, the compiler warns us, this is infinite recursion which probably wasn't what you wanted.
G++ has to emit code here to recurse infinitely, so it's not as though there's no opportunity to say "Huh, that probably won't be what they meant"
C++ compilers had warnings about infinite recursion for years now (since at least 2015 for clang)
Fair. That's actually crazy - I dug into this more and found the chosen Boost package fails tests on the chosen compiler, and so if they'd done even a cursory check to see if what they're doing could make sense there'd be red flags everywhere.
So the overall story is mostly "Our QA is garbage".
You don't have to use all the fancy new features though. Personally I just stick to C++98 for the most part, unless I really want to use auto or lambdas for some reason, then I might use 11, but I won't go higher.
C++ 11 with lambdas is so much nicer than 98, but even if 14, 17, 20 and 23 have been minor in comparison the accumulated changes have been radical in making what was introduced in 11 into something really useful.
Making anything remotely useful out of templates was deeply into hideous SFINAE-land (substitution-failure-is-not-an-error) leading to horrible unreadable templates during 98 (and the variable-number templates in 11 while being useful only made it explode in horrendeous hacks).
"if constexpr" from C++ 17 and forward actually makes template-expansions not too horrid. you can do template expansions that reads mostly like regular if-elseif-else clauses (and I think that was perhaps part of the impetus for Zig's comptime, starting from this point with a clean slate instead of going through regular template evolution hell).
The horrendous hacks went away with concepts. SFINAE is dead. Spaceship operator, while perhaps not ideal from every perspective, radically simplifies the workload of implementing comparators.
Eh, you’re probably missing out. I remember C++20 being really convenient in comparison, though I forget why.
Scala has the advantage (and disadvantage) of not caring one lick about backwards compatibility. They were perfectly happy to burn it all to the ground and redo the language's syntax in v3. And even point releases of Scala frequently have breaking changes.
My only question is how this operator== override eluded the g++ test suite:
https://osec.io/blog/2025-08-11-compiler-bug-causes-compiler...
All test suites have coverage gaps. The fixing commit adds tests. https://gcc.gnu.org/cgit/gcc/commit/?id=c1e54c82a9e1855499ef...
The better question, in my opinion, is how many other known defects are just sitting there in the GNU buganizer with good reports for more than a decade.
I brain-typo’d the title into a 12-year-old girl’s bug taking down Solidity and this, frankly, does not live up to that hype