简体   繁体   中英

What is the rationale for the C++ standard not allowing reinterpret_cast<int>( aFloatValue )?

Or equivalently

    reinterpret_cast<int64>( aDoubleValue )

Allowing such a reinterpret_cast would not introduce any aliasing issues.

I understand that using memcpy to replicate bytes from a variable of one type into a variable of another type can achieve the necessary effect. And I understand that mature compilers with powerful optimizers can do wonderful things with such memcpy constructs.

That said I happen to be a compiler-writer. I am very aware of the many forms of optimization that must exist and the many preconditions that have to be met in order to pull off those dramatic optimizations. Do we really want to assume that every compiler is that powerful or that every programmer will write code successfully satisfying all of the necessary preconditions? Can we really fault programmers using non-mainstream compilers for being dubious that such a hoped-for optimization will occur?

The need to inspect the bits of a floating point values arises fairly often. Do we really want to insist that every programmer encountering such a need traffic in address-taken variables, char* exceptions to type aliasing rules, memcpy magic, etc?

The "new" (now pretty old) forms of casting provided in C++ are all basically subsets of things you can do with C-style casts ("basically" because they have a few minor additions like dealing with references, that just don't exist in C).

To get the equivalent of a reinterpret_cast with a C-style cast, you do something like:

int a = *(int *)&some_float;

So, with a reinterpret_cast , you do pretty much the same things, just changing the syntax for the cast itself with a reinterpret_cast instead:

int a = *reinterpret_cast<int *>&some_float;

As for defining what this does, so you can do it without violating any strict aliasing rules and such: I suspect the committee would probably be happy to consider a really well written proposal--I suspect the problem right now is that most think it would take a lot of work, and payoff would be minimal.

If the real intent is to support looking at the bits of a floating point number, it might be simpler to define something like a constructor for a bitset::bitset<float> or something on that order, to give a type that's already explicitly defined to give access to bits (though it would still probably be non-trivial to define how it's supposed to work in a way that's at all portable).

If all you want is a function that converts a float into its sequence of bits, memcpy can do that without running afoul of the strict aliasing rule:

unsigned int ConvertFloat(float f)
{
  unsigned int ret;
  std::memcpy(&ret, &f, sizeof(unsigned int));
  return ret;
}

Live example.

You could even make a general template function for converting one type to another. One that would static_assert or SFINAE-check if the arguments are trivially-copyable.

In your line of work, converting floats to integers is a semi-frequent operation. But that's simply not true for most C++ users (or even most C users). So there is no widespread need for such a conversion operation.

Furthermore, the C++ standard doesn't require an implementation to provide any particular representation of a float . So even if the standard provided such a function, it couldn't tell you what it actually returned. There's not even guarantee that float can fit into an unsigned int .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM