Fix endianness bug in write_digit2_separated - #2699
Conversation
|
I can confirm this PR fixes the issue: |
| #ifndef _WIN32 | ||
| # if defined(__GNUC__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ | ||
| digits = __builtin_bswap64(digits); | ||
| # else | ||
| if (is_big_endian()) { | ||
| digits = ((digits & 0xff00000000000000ull) >> 56) | | ||
| ((digits & 0x00ff000000000000ull) >> 40) | | ||
| ((digits & 0x0000ff0000000000ull) >> 24) | | ||
| ((digits & 0x000000ff00000000ull) >> 8) | | ||
| ((digits & 0x00000000ff000000ull) << 8) | | ||
| ((digits & 0x0000000000ff0000ull) << 24) | | ||
| ((digits & 0x000000000000ff00ull) << 40) | | ||
| ((digits & 0x00000000000000ffull) << 56); | ||
| } | ||
| # endif | ||
| #endif | ||
| memcpy(buf, &digits, 8); |
There was a problem hiding this comment.
I suggest using std::reverse_copy instead.
There was a problem hiding this comment.
Done.
And improve is_big_endian() with using of predefined macro. This check is compile time now if it possible (to avoid many is_big_endian() calls on little endian system and on GCC like compilers).
| #ifdef _WIN32 | ||
| constexpr auto is_big_endian() -> bool { return false; } | ||
| #elif defined(__BIG_ENDIAN__) | ||
| constexpr auto is_big_endian() -> bool { return true; } | ||
| #elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) | ||
| constexpr auto is_big_endian() -> bool { | ||
| return __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__; | ||
| } | ||
| #else |
There was a problem hiding this comment.
I suggest moving the ifdefs into the body of is_big_endian to avoid repeating its signature. I don't think we care about constexpr here, it will be inlined and optimized away.
| memcpy(tmp, &digits, 8); | ||
| std::reverse_copy(tmp, tmp + 8, buf); |
There was a problem hiding this comment.
why not std::reverse_copy(digits, digits + 8, buf)?
There was a problem hiding this comment.
digits is unsigned long long.
Without memcpy into temp buffer this is UB.
There was a problem hiding this comment.
Ah, indeed. Let's at least turn 8 into a constant then.
|
Thank you! |
Fix issue #2698
Need testing on big-endian platform.CC @xvitaly