On 2024-05-04 15:33, Collin Funk wrote:

But I don't think C23 has the conversion macros:

     /* big endian 32 to host.  */
     uint32_t be32toh (uint32_t);
     /* little endian 32 to host.  */
     uint32_t le32toh (uint32_t);

Yes, those might be a good reason for a Gnulib endian module, to support endian.h GNU-style. Ideally it would be implemented by appealing to stdbit.h when that's helpful.


Since <sys/endian.h> seems resonably portable,

I assume you mean <endian.h>? There's no <sys/endian.h> on my Ubuntu system.

     $ echo | gcc -dM -E - | grep 'ENDIAN'
     #define __ORDER_LITTLE_ENDIAN__ 1234
     #define __FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__
     #define __ORDER_PDP_ENDIAN__ 3412
     #define __ORDER_BIG_ENDIAN__ 4321
     #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__

Although that's a start, we'll need more of course. Here's what I have so far for my prototype stdbit.in.h, but it needs more work. This sort of thing used to be even trickier (see gl_BIGENDIAN and gl_MULTIARCH) but I hope we can dispense with that complexity nowadays (by using something like the following complexity instead :-).

  /* Define the native endianness.  Prefer predefined macros to #include
     directives, to avoid namespace pollution.  */

  /* GCC and Clang define __BYTE_ORDER__ etc.
     ARM compilers define __BIG_ENDIAN etc.
     Oracle Studio defines __SUNPRO_C etc.
     Some platforms work only on little-endian platforms.  */
  #if (defined __BYTE_ORDER__ && defined __ORDER_BIG_ENDIAN__ \
       && defined __ORDER_LITTLE_ENDIAN__)
  # define __STDC_ENDIAN_BIG__ __ORDER_BIG_ENDIAN__
  # define __STDC_ENDIAN_LITTLE__ __ORDER_LITTLE_ENDIAN__
  # define __STDC_ENDIAN_NATIVE__ __BYTE_ORDER__
  #elif (defined __SUNPRO_C ? defined __sparc \
         : 0)
  # define __STDC_ENDIAN_NATIVE__ __STDC_ENDIAN_BIG__
  #elif ((defined __BYTE_ORDER__ && defined __ORDER_BIG_ENDIAN__ \
          && defined __ORDER_BIG_ENDIAN__) \
         ? __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ \
         : defined __SUNPRO_C ? !defined __sparc \
         : (defined _WIN32 || defined __CYGWIN__ || defined __EMX__ \
            || defined __MSDOS__ || defined __DJGPP__) ? 1 \
         : 0)
  # define __STDC_ENDIAN_NATIVE__ __STDC_ENDIAN_LITTLE__
  #else
  # ifdef __has_include
  #  if __has_include (<endian.h>)
  #   include <endian.h>
  #  endif
  # endif
# if defined __BIG_ENDIAN && defined __LITTLE_ENDIAN && defined __BYTE_ORDER
  #  define __STDC_ENDIAN_BIG__ __BIG_ENDIAN
  #  define __STDC_ENDIAN_LITTLE__ __LITTLE_ENDIAN
  #  define __STDC_ENDIAN_NATIVE__ __BYTE_ORDER
  # endif
  # if defined BIG_ENDIAN && defined LITTLE_ENDIAN && defined BYTE_ORDER
  #  define __STDC_ENDIAN_BIG__ BIG_ENDIAN
  #  define __STDC_ENDIAN_LITTLE__ LITTLE_ENDIAN
  #  define __STDC_ENDIAN_NATIVE__ BYTE_ORDER
  # endif
  #endif
  #ifndef __STDC_ENDIAN_BIG__
  # define __STDC_ENDIAN_BIG__ 4321
  #endif
  #ifndef __STDC_ENDIAN_LITTLE__
  # define __STDC_ENDIAN_LITTLE__ 1234
  #endif
  #ifndef __STDC_ENDIAN_NATIVE__
  /* __STDC_ENDIAN_NATIVE__ is not defined on this platform.
     If this doesn't suffice for you, please email a fix
     to <bug-gnulib@gnu.org>.  */
  #endif


Reply via email to