Thread: Using ASSUME in place of ASSERT in non-assert builds

Using ASSUME in place of ASSERT in non-assert builds

From
Benjamin Coutu
Date:
Hello,

I noticed that Andres recently introduced pg_assume into the codebase - great addition!

That got me thinking: some projects (like PHP) map the ASSERT macro to ASSUME in non-assert builds. The rationale is
thatASSERT typically expresses a tautology, something the programmer believes to be always true. So in builds where
assertionsare compiled out, we can still pass that information to the optimizer via ASSUME.
 

This approach has the advantage of keeping the semantics consistent: developers write ASSERT(...) as usual, and the
compilereither enforces it at runtime (assert builds) or uses it as a hint (non-assert builds). There's no need to
writeseparate logic or macros depending on build type. And we get the benefits of both safety and optimization.
 

Was this strategy considered before introducing pg_assume, or did I miss that part of the discussion?

Cheers

-- 

Benjamin Coutu
http://www.zeyos.com



Re: Using ASSUME in place of ASSERT in non-assert builds

From
Tom Lane
Date:
Benjamin Coutu <ben.coutu@zeyos.com> writes:
> That got me thinking: some projects (like PHP) map the ASSERT macro to ASSUME in non-assert builds. The rationale is
thatASSERT typically expresses a tautology, something the programmer believes to be always true. So in builds where
assertionsare compiled out, we can still pass that information to the optimizer via ASSUME. 

My gut instinct is that this would not help much; we don't typically
write assertions that would help the compiler all that much.  And
in any case, to my mind there is a considerable difference in goals
between Assert and Assume, which I'd prefer not to fuzz like this.

            regards, tom lane



Re: Using ASSUME in place of ASSERT in non-assert builds

From
Andres Freund
Date:
Hi,

On 2025-07-10 16:24:08 +0200, Benjamin Coutu wrote:
> I noticed that Andres recently introduced pg_assume into the codebase -
> great addition!
>
> That got me thinking: some projects (like PHP) map the ASSERT macro to
> ASSUME in non-assert builds. The rationale is that ASSERT typically
> expresses a tautology, something the programmer believes to be always
> true. So in builds where assertions are compiled out, we can still pass that
> information to the optimizer via ASSUME.

I don't think that is a good idea to do in general:

- plenty asserts have costs associated with them and something like
  pg_assume() shouldn't be used if the evaluation isn't obviously trivial

- we do sometimes want to continue on in release builds, even if we would have
  triggered an assert failure. You can't do that if you map all asserts to
  assumes, since it'll often lead the compiler to generate bogus code for that
  case.


> This approach has the advantage of keeping the semantics consistent:
> developers write ASSERT(...) as usual, and the compiler either enforces it
> at runtime (assert builds) or uses it as a hint (non-assert builds). There's
> no need to write separate logic or macros depending on build type. And we
> get the benefits of both safety and optimization.

Note that pg_assume() does turn into an Assert in an assertion enabled build,
so if you add an assert you now can choose to use pg_assume() if the release
build should be influenced.


> Was this strategy considered before introducing pg_assume, or did I miss
> that part of the discussion?

No, it wasn't. It seemed like a rather obviously bad idea to me, and the
primary motivation in this case really was to get rid of warnings like the one
addressed in te subsequent commit.

Greetings,

Andres Freund