Hi all,I'd like to propose a bit_cast function.bit_cast<T>(x) would get the bits of x, and reinterpret them as the bits of a value of type T.
For example, you would be able to writefloat x = 1.0f;const uint32_t y = bit_cast<uint32_t>(x);And then y would have the value 0x3f800000.
On 2015–10–07, at 2:28 PM, Arthur O'Dwyer <arthur....@gmail.com> wrote:The reddit discussion points out that one disadvantage of the "easy to write" version is that it's not constexpr.But is that an argument in favor of bit_cast<>, or an argument in favor of constexpr memcpy? (It's not a crazy idea. We already have constexpr for-loops and constexpr assignments; the problem is that we currently lack a constexpr way to talk about pointers and addresses.)
On Tuesday, October 6, 2015 at 12:57:36 PM UTC-7, Nicholas Chapman wrote:Hi all,I'd like to propose a bit_cast function.bit_cast<T>(x) would get the bits of x, and reinterpret them as the bits of a value of type T.For example, you would be able to writefloat x = 1.0f;const uint32_t y = bit_cast<uint32_t>(x);And then y would have the value 0x3f800000.Do you want exactly this?
template<class T, class U>T bit_cast(U u){static_assert(sizeof(T) == sizeof(U));T result;memcpy(&result, &u, sizeof u);return result;}If so, I think the C++ language doesn't provide it because it's easy to write on your own.
template<class T, class U>T bit_cast(U u){static_assert(sizeof(T) == sizeof(U));T result;memcpy(&result, &u, sizeof u);return result;}If so, I think the C++ language doesn't provide it because it's easy to write on your own.Yes, basically I want exactly that.
I think there's a big difference between "easy to write on your own" and "easy to know that this is the right way to do the thing". I think having bit_cast would be tremendously valuable as a certification of this being the right thing to do, or the right way to do it.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Accessing an inactive member of a union is undefined behaviour for any type,
except the active and the inactive are aggregates, share the same initial
sequence and you're accessing data in that sequence.
On Thursday 08 October 2015 15:48:16 Myriachan wrote:
> On Thursday, October 8, 2015 at 8:22:36 AM UTC-7, Thiago Macieira wrote:
> > Accessing an inactive member of a union is undefined behaviour for any
> > type,
> > except the active and the inactive are aggregates, share the same initial
> > sequence and you're accessing data in that sequence.
>
> I wish that this were instead that accessing the inactive member of a union
> is defined as reinterpreting the object representation as the new type.
There was some language in some draft, somewhere, that said exactly that. It
in fact blessed the GCC/Clang/Visual Studio behaviour. It's no longer there.
On Friday 09 October 2015 06:54:35 Edward Catmur wrote:
> On Friday, 9 October 2015 00:22:13 UTC+1, Thiago Macieira wrote:
> > > I wish that this were instead that accessing the inactive member of a
> > > union
> > > is defined as reinterpreting the object representation as the new type.
>
> Could you explain why? Isn't memcpy enough?
It relies on the compiler properly optimising it. It doesn't always.
On Friday, October 9, 2015 at 9:22:59 AM UTC-7, David Krauss wrote:
> On 2015–10–09, at 11:52 PM, Jared Grubb <jared...@gmail.com> wrote:
>
> However, should this algorithm be SFINAE-protected with a std::is_trivially_copyable check (I think this is the correct one)? You could include a std::unsafe_bit_copy to operate without the SFINAE check.
What’s the significance of trivial copyability when you’re reinterpreting the bits as some other type?
I believe that both the source and destination types must be trivially-copyable in order for a memcpy operation between them to have any safe meaning.
Although I'm not 100% certain that I'm picking the right trait here. Maybe "is_pod" is the right SFINAE check here? Maybe it's a combination of a couple? My point is that you need some SFINAE-check on this algorithm to make it safe. I am having trouble thinking of an example where this would prohibit something that would work otherwise (and in that case, add an unsafe version but provide a safe one to double-check what programmers are attempting).
I'm pretty sure `is_pod` is more strict than is absolutely necessary.
Trivial copyability is needed for `memcpy` to actually produce defined results. However, trivial copyability alone only allows copying between two objects of the same type. If you want to memcpy between two objects of different types, then in order to get defined behavior, the types must be layout compatible.
Of course, the OP clearly does not care about what is and is not well-defined. Binary int-to-float conversions do not produce standard-defined behavior. So if the goal is to make bit_copy<int, float> actually work, you don't care about what is technically legal C++.
The standard can't ensure every bit_cast is defined, not even when the destination type is trivially copyable; the source value could be the object representation of a trap representation in the target type.
It's still possible to define bit_cast without reference to memcpy, though: something like "If the object representation of the source value contains the value representation of a value of the target type, returns that value; otherwise, the result is undefined." That gets us the expected behavior on x86 without restricting other platforms.
--
---
You received this message because you are subscribed to a topic in the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this topic, visit https://groups.google.com/a/isocpp.org/d/topic/std-proposals/3H6-V9_qVmQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to std-proposal...@isocpp.org.
The standard can't ensure every bit_cast is defined, not even when the destination type is trivially copyable; the source value could be the object representation of a trap representation in the target type.
It's still possible to define bit_cast without reference to memcpy, though: something like "If the object representation of the source value contains the value representation of a value of the target type, returns that value; otherwise, the result is undefined." That gets us the expected behavior on x86 without restricting other platforms.
template <class Target, class Source>
Target bit_cast(const Source &src);