Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fmtlib fails to compile in bit_cast on RAD Studio bcc32c (Win32) due long double and unsigned sizes #4245

@jsirpoma

Description

@jsirpoma

fmtlib fails to compile on RAD Studio bcc32c compiler in bit_cast when From is long double:

constexpr auto size = static_cast<int>(sizeof(From) / sizeof(unsigned));

The size of data_t will be smaller than long double. This happens because on bcc32c:

  • long double is 10 bytes (80 bits)
  • unsigned is 4 bytes (32 bits)

So the size used in data_t is calculated to be 2 and results in data_t size of 8 bytes (2*unsigned) and is smaller than the long double.

I am unsure of the proper fix for this, but using unsigned short for the calculation and data_t does fix this for bcc32c (size is 5 and resulting data_t size is 10). So what I did was (changes bcc32c only):

// A heterogeneous bit_cast used for converting 96-bit long double to uint128_t
// and 128-bit pointers to uint128_fallback.
template <typename To, typename From, FMT_ENABLE_IF(sizeof(To) > sizeof(From))>
inline auto bit_cast(const From& from) -> To {
#if !defined(__WIN32) || !defined(__WIN64)
  using d_t = unsigned short;
#else
  using d_t = unsigned;
#endif
  constexpr auto size = static_cast<int>(sizeof(From) / sizeof(d_t));
  struct data_t {
    d_t value[static_cast<unsigned>(size)];
  } data = bit_cast<data_t>(from);
  auto result = To();
  if (const_check(is_big_endian())) {
    for (int i = 0; i < size; ++i)
      result = (result << num_bits<d_t>()) | data.value[i];
  } else {
    for (int i = size - 1; i >= 0; --i)
      result = (result << num_bits<d_t>()) | data.value[i];
  }
  return result;
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions