C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Constant-time selection primitive following memset_explicit precedent

From: Jens Maurer <jens.maurer_at_[hidden]>
Date: Sun, 14 Dec 2025 11:43:25 +0100
On 12/14/25 07:35, Shivam Kunwar wrote:
> With __builtin_ct_select (Probably coming in LLVM 22), you're creating a
> constant time zone, and the intrinsic is just a black box, the optimizer
> evaluates the arguments, hands them to something it can't see through,
> and gets a result back, so there's nowhere for expressions to escape to.
>
> And I would say hide_value idea is even more minimal:
> T hide_value(T x) noexcept;
> // Returns x unchanged, but optimizer must forget everything about its
> value
>
> and then we build select on top:
> T select_explicit(bool cond, T a, T b) {
> T mask = -(T)(!!cond);
> return (a & hide_value(mask)) | (b & hide_value(~mask));
> }
>
> so here what we are noticing that there is no zones, no barriers, no
> wrapper types, just "this value is now opaque to you" , and the
> optimizer can't simplify (a & hide_value(mask)) because it genuinely
> doesn't know what the mask is anymore.
>
> I guess what I'm asking is, does hide_value hit the same wall as
> value<T>, or is it simple enough to actually work? It's not trying to
> make timing observable in the abstract machine, it's just making the
> optimizer forget specific facts about values.

The notion of "optimizer" does not exist in the C++ standard.
The liberty for optimizers comes from the abstract machine
and what is and is not guaranteed in its context.

For the above example, it would be totally fine for the implementation
to implement the outer bit-wise "or" as a loop over all bits, with
a (branching) condition for each bit value. You might not like the
resulting QoI, but it's a valid implementation strategy for a C++
implementation.

Jens

Received on 2025-12-14 10:43:28