Date: Fri, 27 Mar 2026 09:11:36 -0700
I am not sure what the hold up with gcc is. They have an idiom for it.
This works:
*#define ASSUME(x) do { if (!(x)) __builtin_unreachable(); } while
(0)struct S { bool b;};void callit();void func(S s) { ASSUME(s.b);
if (!s.b) callit();}*
This indicates they have the machinery in place. However, as I noted in a
separate message, it will call functions inside x, making it difficult to
use globally. It looks like this is just a matter of priorities, rather
than a fundamental issue.
I was just reading the steering groups paper:
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p2000r5.pdf
And safety is a major focus coming from them. So I would love to see P2900
style assertions put into the standard library instead of having UB
everywhere. That would also allow an evaluation semantics mode "assume" as
I described previously to leverage those assertions where it was deemed
safe to do so.
Anyway, it looks like this might even be a post-C++29 thing to talk about
as P2900 is just getting ratified and only has experimental support... I
will try and come up with a better benchmark.
On Fri, Mar 27, 2026 at 2:10 AM Ivan Lazaric via Std-Proposals <
std-proposals_at_[hidden]> wrote:
>
> I am not against assume semantic, but will note (some) compilers are not
super strong on using the information from [[assume(...)]] attribute at the
moment
>
> struct S {
> bool b;
> };
>
> void callit();
>
> void func(S s) {
> [[assume(s.b)]];
> if (!s.b) callit();
> }
>
> One would hope func() would be reduced to just a ret instruction, but
with gcc we get:
>
> "func(S)":
> test dil, dil
> je .L4
> ret
> .L4:
> jmp "callit()"
>
> Godbolt of this: https://godbolt.org/z/3bb1fx6E9
> Clang does optimize it out though: https://godbolt.org/z/sqMMrzh4W
>
>
> On Fri, Mar 27, 2026 at 9:57 AM Peter Bindels via Std-Proposals <
std-proposals_at_[hidden]> wrote:
>>
>> P2900 is focused on (functional) safety first and foremost. Any assume
semantic does not make sense, and adding that to the discussion will muddle
the story on what contracts bring first and foremost.
>>
>> That said, the concept of an assume semantic is well-understood, and
many are indeed asking for it. I suspect that compilers will be
implementing it even if the C++ standard does not mention it, and users
will be trying it out, and finding that for correct invocations it indeed
works the same (modulo compiler bugs), while for buggy calls it can have
terrifying optimizations applied based on them not happening.
>>
>> It is probably a good idea to write a paper to propose specifically only
the assume semantic, and to defend that in WG21 with lots of actual
performance data from a code base that uses P2900/C++26 contracts
extensively, to show what its impact is and why that should warrant being
standardized. You will likely get a big discussion on safety, but for
"release builds" as colloquially known they should be effectively what we
have done before.
>>
>> On Fri, Mar 27, 2026 at 5:29 AM Adrian Johnston via Std-Proposals <
std-proposals_at_[hidden]> wrote:
>>>
>>> We have P2900 in the works and it is moving us away from the "roll
>>> your own" situation we have been in with respect to asserts for the
>>> last 37 years. So ergonomics is part of it.
>>>
>>> And as far as I know, P2900 specifies an evaluation semantics mode
>>> without defining how a macro would be defined in terms of the current
>>> evaluation semantics mode. That is one barrier. The other issue is
>>> that the [[assume]] attribute prohibits function calls which is an
>>> issue with global blanket use. (clang has -Wno-assume for function
>>> calls in __builtin_assume, gcc had no satisfactory solution for that
>>> in my tests.)
>>>
>>> Lastly, I think the proposal I am trying to float here encourages more
>>> safety around the use of "assume" semantics. This is because it
>>> provides a way to check your assumptions in a debug build. And safety
>>> is all the rage these days.
>>>
>>>
>>> On Thu, Mar 26, 2026 at 8:22 PM JJ Marr <jjmarr_at_[hidden]> wrote:
>>> >
>>> > I'm a big fan of the idea. Why isn't a macro of an assertion followed
by an assumption sufficient?
>>> >
>>> > On Thu, Mar 26, 2026, 5:41 p.m. Adrian Johnston via Std-Proposals <
std-proposals_at_[hidden]> wrote:
>>> >>
>>> >> Hello,
>>> >>
>>> >> I would like to propose [[assume_assert(expr)]] which would be a
>>> >> hybrid of contract_assert and [[assert(expr)]] that selects between
>>> >> the behavior of the two depending on the evaluation semantics mode as
>>> >> described in P2900:
>>> >>
>>> >> - ignore: same as [[assume(expr)]]
>>> >> - observe: same as contract_assert(expr)
>>> >> - enforce: same as contract_assert(expr)
>>> >> - quick-enforce: same as contract_assert(expr)
>>> >>
>>> >> These have the benefit of alerting the developer in a debug build
when
>>> >> [[assume(expr)]] has been misused and hopefully reduce the amount of
>>> >> undefined behavior associated with the use of [[assume(expr)]].
>>> >>
>>> >> As an alternative to this approach, an evaluation semantics mode
>>> >> "assume" could be added which would convert all P2900 contract
>>> >> assertions to have [[assume(expr)]] semantics.
>>> >>
>>> >> proposed evaluation semantics:
>>> >> - ignore: unchanged
>>> >> - observe: unchanged
>>> >> - enforce: unchanged
>>> >> - quick-enforce: unchanged
>>> >> - assume: replace pre(expr), post(expr), post(ret, expr),
>>> >> contract_assert(expr) with [[assume(expr)]] semantics.
>>> >>
>>> >> The one major issue here is that the current standard says an assume
>>> >> statement cannot call functions, and this limitation would not be
>>> >> enforceable across a non-trivial application. Instead, I would
propose
>>> >> that function calls would result in the expression being ignored when
>>> >> evaluation semantics are set to mode "assume". In this case a warning
>>> >> would not be recommended as that would break strict builds.
>>> >>
>>> >> I have implemented this kind of [[assume_assert(expr)]] using
>>> >> compiler-specific intrinsics and used it for every last assertion in
a
>>> >> non-trivial codebase. It worked great, and so I am recommending it
for
>>> >> the next version of C++26.
>>> >>
>>> >> I would also like to suggest things like assume_pre (expr) and
>>> >> assume_post (expr) although that pollutes the global namespace for a
>>> >> feature that is less commonly used.
>>> >>
>>> >> My recommendation would be to add [[assume_assert(expr)]] and
>>> >> evaluation semantics mode "assume".
>>> >>
>>> >> Regards,
>>> >> Adrian
>>> >> --
>>> >> Std-Proposals mailing list
>>> >> Std-Proposals_at_[hidden]
>>> >> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>> --
>>> Std-Proposals mailing list
>>> Std-Proposals_at_[hidden]
>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
This works:
*#define ASSUME(x) do { if (!(x)) __builtin_unreachable(); } while
(0)struct S { bool b;};void callit();void func(S s) { ASSUME(s.b);
if (!s.b) callit();}*
This indicates they have the machinery in place. However, as I noted in a
separate message, it will call functions inside x, making it difficult to
use globally. It looks like this is just a matter of priorities, rather
than a fundamental issue.
I was just reading the steering groups paper:
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p2000r5.pdf
And safety is a major focus coming from them. So I would love to see P2900
style assertions put into the standard library instead of having UB
everywhere. That would also allow an evaluation semantics mode "assume" as
I described previously to leverage those assertions where it was deemed
safe to do so.
Anyway, it looks like this might even be a post-C++29 thing to talk about
as P2900 is just getting ratified and only has experimental support... I
will try and come up with a better benchmark.
On Fri, Mar 27, 2026 at 2:10 AM Ivan Lazaric via Std-Proposals <
std-proposals_at_[hidden]> wrote:
>
> I am not against assume semantic, but will note (some) compilers are not
super strong on using the information from [[assume(...)]] attribute at the
moment
>
> struct S {
> bool b;
> };
>
> void callit();
>
> void func(S s) {
> [[assume(s.b)]];
> if (!s.b) callit();
> }
>
> One would hope func() would be reduced to just a ret instruction, but
with gcc we get:
>
> "func(S)":
> test dil, dil
> je .L4
> ret
> .L4:
> jmp "callit()"
>
> Godbolt of this: https://godbolt.org/z/3bb1fx6E9
> Clang does optimize it out though: https://godbolt.org/z/sqMMrzh4W
>
>
> On Fri, Mar 27, 2026 at 9:57 AM Peter Bindels via Std-Proposals <
std-proposals_at_[hidden]> wrote:
>>
>> P2900 is focused on (functional) safety first and foremost. Any assume
semantic does not make sense, and adding that to the discussion will muddle
the story on what contracts bring first and foremost.
>>
>> That said, the concept of an assume semantic is well-understood, and
many are indeed asking for it. I suspect that compilers will be
implementing it even if the C++ standard does not mention it, and users
will be trying it out, and finding that for correct invocations it indeed
works the same (modulo compiler bugs), while for buggy calls it can have
terrifying optimizations applied based on them not happening.
>>
>> It is probably a good idea to write a paper to propose specifically only
the assume semantic, and to defend that in WG21 with lots of actual
performance data from a code base that uses P2900/C++26 contracts
extensively, to show what its impact is and why that should warrant being
standardized. You will likely get a big discussion on safety, but for
"release builds" as colloquially known they should be effectively what we
have done before.
>>
>> On Fri, Mar 27, 2026 at 5:29 AM Adrian Johnston via Std-Proposals <
std-proposals_at_[hidden]> wrote:
>>>
>>> We have P2900 in the works and it is moving us away from the "roll
>>> your own" situation we have been in with respect to asserts for the
>>> last 37 years. So ergonomics is part of it.
>>>
>>> And as far as I know, P2900 specifies an evaluation semantics mode
>>> without defining how a macro would be defined in terms of the current
>>> evaluation semantics mode. That is one barrier. The other issue is
>>> that the [[assume]] attribute prohibits function calls which is an
>>> issue with global blanket use. (clang has -Wno-assume for function
>>> calls in __builtin_assume, gcc had no satisfactory solution for that
>>> in my tests.)
>>>
>>> Lastly, I think the proposal I am trying to float here encourages more
>>> safety around the use of "assume" semantics. This is because it
>>> provides a way to check your assumptions in a debug build. And safety
>>> is all the rage these days.
>>>
>>>
>>> On Thu, Mar 26, 2026 at 8:22 PM JJ Marr <jjmarr_at_[hidden]> wrote:
>>> >
>>> > I'm a big fan of the idea. Why isn't a macro of an assertion followed
by an assumption sufficient?
>>> >
>>> > On Thu, Mar 26, 2026, 5:41 p.m. Adrian Johnston via Std-Proposals <
std-proposals_at_[hidden]> wrote:
>>> >>
>>> >> Hello,
>>> >>
>>> >> I would like to propose [[assume_assert(expr)]] which would be a
>>> >> hybrid of contract_assert and [[assert(expr)]] that selects between
>>> >> the behavior of the two depending on the evaluation semantics mode as
>>> >> described in P2900:
>>> >>
>>> >> - ignore: same as [[assume(expr)]]
>>> >> - observe: same as contract_assert(expr)
>>> >> - enforce: same as contract_assert(expr)
>>> >> - quick-enforce: same as contract_assert(expr)
>>> >>
>>> >> These have the benefit of alerting the developer in a debug build
when
>>> >> [[assume(expr)]] has been misused and hopefully reduce the amount of
>>> >> undefined behavior associated with the use of [[assume(expr)]].
>>> >>
>>> >> As an alternative to this approach, an evaluation semantics mode
>>> >> "assume" could be added which would convert all P2900 contract
>>> >> assertions to have [[assume(expr)]] semantics.
>>> >>
>>> >> proposed evaluation semantics:
>>> >> - ignore: unchanged
>>> >> - observe: unchanged
>>> >> - enforce: unchanged
>>> >> - quick-enforce: unchanged
>>> >> - assume: replace pre(expr), post(expr), post(ret, expr),
>>> >> contract_assert(expr) with [[assume(expr)]] semantics.
>>> >>
>>> >> The one major issue here is that the current standard says an assume
>>> >> statement cannot call functions, and this limitation would not be
>>> >> enforceable across a non-trivial application. Instead, I would
propose
>>> >> that function calls would result in the expression being ignored when
>>> >> evaluation semantics are set to mode "assume". In this case a warning
>>> >> would not be recommended as that would break strict builds.
>>> >>
>>> >> I have implemented this kind of [[assume_assert(expr)]] using
>>> >> compiler-specific intrinsics and used it for every last assertion in
a
>>> >> non-trivial codebase. It worked great, and so I am recommending it
for
>>> >> the next version of C++26.
>>> >>
>>> >> I would also like to suggest things like assume_pre (expr) and
>>> >> assume_post (expr) although that pollutes the global namespace for a
>>> >> feature that is less commonly used.
>>> >>
>>> >> My recommendation would be to add [[assume_assert(expr)]] and
>>> >> evaluation semantics mode "assume".
>>> >>
>>> >> Regards,
>>> >> Adrian
>>> >> --
>>> >> Std-Proposals mailing list
>>> >> Std-Proposals_at_[hidden]
>>> >> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>> --
>>> Std-Proposals mailing list
>>> Std-Proposals_at_[hidden]
>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Received on 2026-03-27 16:11:48
