A few months ago there was a suggestion on emacs-devel to use __builtin_bswap functions when available [1]. While I agree that GCC can deal with the optimizations properly, I noted an important difference between the macros in byteswap.h.in and inline functions provided by glibc.
Using this test program to compare the real glibc header to a macro copy-pasted from the replacement header: ====================================== #define _GNU_SOURCE 1 #include <stdio.h> #include <inttypes.h> #include <byteswap.h> #define bswap_32_macro(x) ((((x) & 0x000000FF) << 24) | \ (((x) & 0x0000FF00) << 8) | \ (((x) & 0x00FF0000) >> 8) | \ (((x) & 0xFF000000) >> 24)) int main (void) { uint32_t value = 0x12345678; uint32_t value_macro = 0x12345678; printf ("1. %#" PRIX32 "\n", bswap_32 (value++)); printf ("2. %#" PRIX32 "\n", bswap_32_macro (value_macro++)); printf ("3. %#" PRIX32 "\n", value); printf ("4. %#" PRIX32 "\n", value_macro); return 0; } ====================================== We get the output: $ ./a.out 1. 0X78563412 2. 0X78563412 3. 0X12345679 4. 0X1234567C I would like to deal with this concern before I implement the replacement for <endian.h>. I think the best decision is to use 'extern inline' to match the behavior of glibc. Any other opinions on this? Also if we can agree upon making sure these are defined as functions, what is the proper way to test it in a configure script? My instinct tells me that assigning a function pointer to bswap_16, etc. would fail if they are macros but I am not sure the "standard" way of performing that check. Collin [1] https://lists.gnu.org/archive/html/emacs-devel/2024-03/msg00736.html