C++ Logo

std-proposals

Advanced search

Re: [std-proposals] More C++ bit manipulation utilities

From: Jan Schultke <janschultke_at_[hidden]>
Date: Fri, 27 Jun 2025 06:57:22 +0200
Hey Simon,

Those are some fair points; I don't think set_bit etc. would be
high-consensus. Maybe I should drop them.

What are your thoughts on sign_fill specifically? That is the one function
out of all of these which is of great use, and which would be a must-have
to me. That is because the alternative is

x >> (UINT_WIDTH - 1)
or
x >> (std::numeric_limits<unsigned>::digits - 1)

If you want to write this generically for some type T, the first option
goes out the window, and the second option is very annoying because it's
verbose, and because ::digits gives you different results for signed and
unsigned types.

You can write (1 >> x) & 1 just fine to get the xth bit for any type, but
if you want a generic sign fill, you're almost certainly going to need a
function that does that. Maybe the proposal should just be for that one
function.


On Fri, 27 Jun 2025 at 06:40, Simon Schröder via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> I don’t mind the “assembler-like” bit operations we already have. There
> are few places where the everyday programmer needs bit manipulations. One
> major area this comes to mind is flags. However, I’d rather see a different
> proposal for how to properly handle flags instead. Another area I see use
> is for binary file formats. But, that’s usually something for expert
> programmers. All other areas will be highly specific to a niche and
> programmers should then learn the appropriate tools (i.e. bit
> manipulations) specific to that niche. Maybe you are also thinking about
> embedded systems. But, maybe it is also a good thing that embedded
> programmers need to get a little closer to the hardware in their
> programming. Your abstraction will separate them from their hardware
> instead.
>
> Concerning an optimal solution for some of your proposed function: If
> performance for these functions is of concern to a programmer he lives in a
> very specific niche and should know the proper tools for his application.
> For most programmers it is perfectly fine if the solution is not optimal;
> it will never be the performance killer inside a loop for them.
>
> To me, it sounds like you want abstractions for those programmers who need
> to be really close to the hardware (sounds almost like an oxymoron). I
> personally don’t see a general need for this (see my explanation above).
> Still, I also wouldn’t oppose it.
>
> On Jun 26, 2025, at 1:03 PM, Jan Schultke via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
> 
> Hi,
>
> I'm interested in how much appetite there would be for the following set
> of functions in <bit>:
>
> template<class T>
> T sign_fill(T x) noexcept;// Fills the integer with the most significant bit of x.
> template<class T>
> T bit_mask(T x) noexcept;// Returns (T{1} << x) - T{1};
> template<class T>
> bool get_bit(T x, int i);// Gets ith bit in x.
> template<class T>
> T set_bit(T x, int i);template<class T>
> T set_bit(T x, int i, bool b);// Sets ith bit in x to 1 and b, respectively.
> template<class T>
> T reset_bit(T x, int i);// Sets ith bit in x to 0.
> template<class T>
> T flip_bit(T x, int i);// Sets ith bit in x to its complement.
>
>
> These kinds of things are building blocks used in bit manipulation all the
> time.
>
> It's also not trivial to get optimal codegen for all compilers on all
> architectures. I've actually overhauled the top answer on the StackOverflow
> post at https://stackoverflow.com/q/47981/5740428, and I can say from
> experience that not every way to write set_bit(T, int, bool) is equally
> good.
>
> Sign-filling is a pretty common technique, and writing it out by hand is
> somewhat tedious because it requires going through std::numeric_limits to
> do it generically.
>
> Even if we leave these arguments aside, the problem with writing say, (x
> | (1 << i)) instead of set_bit(x, i) is the lack of expressiveness. It's
> somewhat like writing inline assembly and then puzzling together that cmp
> and je collectively perform a jump if two registers are unequal. It's
> easy if you did it 1000 times before, but not obvious to novice readers at
> all.
>
> The question is mainly where to draw the line. There are tons of different
> bit manipulation techniques, like isolating the lowest set bit, etc.
> However, none of these are anywhere near as common as simple
> setting/getting specific bits. I cherry-picked creating bit masks and
> sign-filling because they stand out from the crowd, in my experience. Maybe
> I could collect some data on this.
>
>
> Jan
> --
> 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 2025-06-27 04:57:37