- On endianness, many #ifdefs, and the need thereof - 7 Updates
- alloca()-support - 7 Updates
- strange issue ... - 8 Updates
- Compile a program from all C and C++ files in current folder - 3 Updates
| David Brown <david.brown@hesbynett.no>: Oct 03 09:48AM +0200 On 02/10/2019 15:54, Scott Lurndal wrote: >> result of this function at compile time and use that in optimisation. > Can it? How does that work when you're cross-compiling to a different > architecture (like a microcontroller, for example)? Try this on <https://godbolt.org> static constexpr bool little_endianess(int num = 1) noexcept { return *reinterpret_cast<char*>(&num) == 1; } bool is_little_endian() { return little_endianess(); } You'll see gcc generate code such as: is_little_endian(): movl $1, %eax ret This is, of course, an optimisation issue - not all compilers can handle it, and you will need to enable optimisation. (And clang throws an wobbly when you have a "reinterpret_cast" in a "constexpr" function. You can just remove the "constexpr", since it doesn't help anyway.) Compilers know their targets, and they know if they are targeting little-endian or big-endian (or mixed-endian). They know that, even if the cpu in question supports both endiannesses - binaries are generated for only one endianness at a time. |
| David Brown <david.brown@hesbynett.no>: Oct 03 09:54AM +0200 On 02/10/2019 17:33, Barry Schwarz wrote: > distinguish between the two cases, thus increasing the run time. > Whether this is a significant consideration obviously depends on the > code. That is the /logical/ behaviour. In practice, a good compiler can evaluate the function at compile time (even though it is not a constant expression), and use this along with dead code elimination to remove the run-time check and code that cannot be called. (Since it logically has the the test, the unused branch of code still has to be valid and compilable code, unlike when you use conditional compilation with the preprocessor.) > tested not to mention the nesting of && and || operations. > OTOH, the function approach will fail if sizeof (int) is 1 (32-bit > char). You can happily combine the approaches: # if (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \ (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN) || \ (defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN) || \ (defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)) || (defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)) || \ defined(__ARMEB__) || defined(__MIPSEB__) || defined(__s390__) || defined(__sparc__) constexpr bool is_big_endian = true; constexpr bool is_little_endian = false; #define IS_BIG_ENDIAN 1 #define IS_LITTLE_ENDIAN 0 #else constexpr bool is_big_endian = false; constexpr bool is_little_endian = true; #define IS_BIG_ENDIAN 0 #define IS_LITTLE_ENDIAN 1
Subscribe to:
Post Comments (Atom)
|
No comments:
Post a Comment