Date: Fri, 27 Mar 2026 10:09:41 +0100
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
>
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
>
Received on 2026-03-27 09:10:01
