On 3/23/25 08:16, Kuan-Wei Chiu wrote:

Interface 3: Multiple Functions
Description: bool parity_odd8/16/32/64()
Pros: No need for explicit casting; easy to integrate
       architecture-specific optimizations; except for parity8(), all
       functions are one-liners with no significant code duplication
Cons: More functions may increase maintenance burden
Opinions: Only I support this approach


OK, so I responded to this but I can't find my reply or any of the followups, so let me go again:

I prefer this option, because:

a. Virtually all uses of parity is done in contexts where the sizes of the items for which parity is to be taken are well-defined, but it is *really* easy for integer promotion to cause a value to be extended to 32 bits unnecessarily (sign or zero extend, although for parity it doesn't make any difference -- if the compiler realizes it.)

b. It makes it easier to add arch-specific implementations, notably using __builtin_parity on architectures where that is known to generate good code.

c. For architectures where only *some* parity implementations are fast/practical, the generic fallbacks will either naturally synthesize them from components via shift-xor, or they can be defined to use a larger version; the function prototype acts like a cast.

d. If there is a reason in the future to add a generic version, it is really easy to do using the size-specific functions as components; this is something we do literally all over the place, using a pattern so common that it, itself, probably should be macroized:

#define parity(x)                               \
({                                              \
        typeof(x) __x = (x);                    \
        bool __y;                               \
        switch (sizeof(__x)) {                  \
                case 1:                         \
                        __y = parity8(__x);     \
                        break;                  \
                case 2:                         \
                        __y = parity16(__x);    \
                        break;                  \
                case 4:                         \
                        __y = parity32(__x);    \
                        break;                  \
                case 8:                         \
                        __y = parity64(__x);    \
                        break;                  \
                default:                        \
                        BUILD_BUG();            \
                        break;                  \
        }                                       \
        __y;                                    \
})
                                

Reply via email to