Site Tools


wiki:stdbit.h

Table of Contents

stdbit.h

Before C23, if you wanted to count the leading zeros in an integer or compute its population count, you either reached for GCC's __builtin_clz and __builtin_popcount, wrote a loop, or pulled in a platform-specific intrinsic. None of these were portable. stdbit.h (C23) standardises bit-manipulation operations so you can use them without the compiler-specific spellings.

#include <stdbit.h>
 
unsigned int x = 0b00101100;  // 44
 
stdc_leading_zeros(x)    // 26  (zero bits before the highest set bit)
stdc_leading_ones(x)     // 0
stdc_trailing_zeros(x)   // 2   (zero bits at the low end)
stdc_trailing_ones(x)    // 0
stdc_count_ones(x)       // 3   (population count / Hamming weight)
stdc_count_zeros(x)      // 29
stdc_has_single_bit(x)   // false (not a power of two)
stdc_bit_width(x)        // 6   (minimum bits needed to represent x)
stdc_bit_floor(x)        // 32  (largest power of two <= x)
stdc_bit_ceil(x)         // 64  (smallest power of two >= x)

The functions are generic: they accept any unsigned integer type and work on its full width. Passing a signed type is a constraint violation.

The same operations existed before C23 — ffs in <strings.h>, GCC's __builtin_* family, POSIX <strings.h>. The problem was inconsistent naming and undefined behaviour on zero inputs. The <stdbit.h> functions are defined for all valid inputs including zero, so stdc_leading_zeros(0) returns the full bit width of the type, not undefined behaviour.

stdc_bit_ceil and stdc_bit_floor replace the classic “next power of two” trick (1u << (32 - __builtin_clz(n))) which was easy to get wrong on edge cases like zero or already-a-power-of-two inputs.

wiki/stdbit.h.md · Last modified: by 127.0.0.1