C++ Logo

std-proposals

Advanced search

Re: [std-proposals] compile_assert draft proposal for feedback

From: Jonathan Grant <jg_at_[hidden]>
Date: Sat, 28 Feb 2026 01:05:02 +0000
Hello Peter
Many thanks for your time looking into this, my notes below.

On 22/02/2026 22:20, Peter Bindels wrote:
> If I can raise a different angle to your proposal...
>
> Suppose we have C++26 contracts. We'll assume the compiler is always using the enforce semantic, and compiles code to always expect all contracts to use the enforce semantic. The compiler is allowed to eliminate contract checks if it can show they can never be reached (under regular as-if rule). Given a function with a contract that has preconditions that make all subsequent calls have only redundant contract checks, it could eliminate all of those checks under as-if rule (since the function couldn't have been entered in those cases). That means that if your code ends up having no unprovable contract checks, it will end up without any relocations to the contract violation handler. You could link to a standard library that does not have such a handler, making any such unproven - not-eliminated - contract check a link-time failure.
>

That sounds good, yes, as-if rule optimization will likely remove all validated checks as they don't generate any code. So won't need a contract violation handler as you say to link to.

The a few ways to stop a single compile I am aware of that can work for compile_assert:
* compiler error attribute
* emit invalid asm("oops");
* refer to a symbol which is missing so linker fails.

Yes, my understanding is that the compiler will likely optimize out redundant later checks of the same thing if the control flow is clear.
May I clarify, I didn't think any C++26 contract implementation has hard compiler_assert style enforce semantics? My understanding is that they are runtime checks like assert()?

* I did make an example of C++ Contracts using compile_assert, so that the Contracts were all evaluated at compile time. That is the pre() contract_assert() and post(). Of course not all programs are this simple. If I was using Contracts, I would prefer to use at compile time.
https://github.com/jonnygrant/compile_assert/blob/main/testsuite/main25_a.cpp

If I needed Contracts at runtime (DbC) I could follow the same pattern, add a runtime_pre(), runtime_post() and runtime_contract().

> Would that accomplish the same thing your feature does?

My understanding is a link failure (not finding the contract violation handler) would mean at least one failing contract remained, but we might not know which contract failed as the diagnostic, or can we specify different violation handler functions? like callbacks in C!

>
> On a second angle, what about having the ability (similar to what Jan Schultke proposed earlier) to mark a function as [[mustprove]] ? In that case we're requesting the compiler or static analyzer to check the function whether all contract checks in the function could be eliminated assuming they were enforced - and if not, to fail the compilation. This limits the blast radius in case a given check can be proven in some places but not others, as it refers to a specific function (instance) being compiled instead of to a given contract check. That, applied in the critical places, would seem to solve the same problem as your compile_assert.
>
> What's your view on these alternate approaches?

I'm grateful for you sharing.

I believe I missed that [[mustprove]] proposal, may I kindly ask if you could share a link?
Would be tricky for some functions to [[mustprove]] constraints. They might call handle_contract_violation() at runtime.

Could you give an example of a contract check being proven and eliminated in once place but not in another? I'd like to understand better.
compile_assert() is a little like that contract_assert() within the body of a function, although compile_assert only ever runs at compile time().

> I haven't sent these out before, as they are IMO not things suitable for standardization. They are both reliant on however well your compiler does optimization and analysis. While your specific compilers can do this reliably to some point, and can be expected to keep up its ability to validate such things in the future, we can not require all compilers to do some specific analysis - or to limit its analysis to a given set of optimizations that could be required of all compilers. At best, we could ask for a standard name for such an attribute so that compilers could all understand the request the same way, but the implementation should be QoI, where compilers can provide either zero support by always failing all of those requests, or maximal support by making the compiler find counterexamples in case it cannot prove a given set, potentially to the point of almost halting progress entirely, depending on the situation the user is in.
> Regards,
> Peter Bindels

You're completely right that different compilers have different strengths, and not all compilers may be able to prove complex conditions. On reflection I thought it's better to only aim to standardize the syntax of compile_assert(expression, message) and leave the extent of the implementation to the compiler. Although I have a working solution using the macro, so we have enough to do many things already (I've not yet found a limitation!)

Thank you again for your feedback.

Regards
Jonathan

Received on 2026-02-28 01:05:08