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