protozero icon indicating copy to clipboard operation
protozero copied to clipboard

config.hpp's endian test silently falls back to little-endian

Open zeha opened this issue 5 months ago • 5 comments

In https://github.com/PowerDNS/pdns/issues/16091 I discovered that config.hpp has an endian check using __BYTE_ORDER, but at least on GCC 15 / GNU libc platforms it doesn't work. Without including <endian.h> the macros are not defined, and config.hpp silently falls back to little endian.

Could an #include <endian.h> be added to config.hpp?

Thanks, Chris

zeha avatar Sep 07 '25 12:09 zeha

As pointed out by @omoerbeek in https://github.com/PowerDNS/pdns/issues/16091#issuecomment-3263784377 and https://github.com/PowerDNS/pdns/issues/16091#issuecomment-3263788379 the standards-compliant thing would be:

  • include endian.h
  • use BYTE_ORDER, LITTLE_ENDIAN, BIG_ENDIAN (no leading or trailing underscores)

Thanks for considering!

zeha avatar Sep 07 '25 13:09 zeha

Unfortunately it is not that easy. endian.h is not part of the C++ standard, it isn't available on all platforms. And protozero is header-only, so there is no build-step we control where we could figure out on what platform we are. So we have to figure out what endianness we have in our own code in C++ only without resorting to any headers. If you have some code for config.hpp that doesn't need endian.h and does the right thing for your platform I'd consider merging a PR.

A workaround for you would be to #include <protozero/config.hpp> and after that set PROTOZERO_BYTE_ORDER in any way that works for you and then include the other protozero includes.

If and when we switch to C++20 which is probably a long way off, we can use the std::endian enum class which will solve this properly.

joto avatar Sep 08 '25 07:09 joto

Right. While many systems have endian.h, not all. macOS is an example.

It might be that testing for the __NAME__ (with __ on both ends) variants of the macros is more robust. At least both g++ and clang++ defines those in all systems I tested without the need for includes. I do not have access to other compilers.

omoerbeek avatar Sep 08 '25 13:09 omoerbeek

@joto how about using a __has_include check to detect endian.h?

kkaefer avatar Oct 16 '25 08:10 kkaefer

__has_include was introduced in C++17, we are still at C++14.

joto avatar Oct 16 '25 09:10 joto