Boost logo

Boost :

Subject: Re: [boost] [endian] Project not maintained
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2016-04-04 09:28:37


On 2016-04-04 14:54, Peter Dimov wrote:
> Gavin Lambert wrote:
>> If you have API that can take a void* or char* (or other
>> block-of-bytes-of-appropriate-size) and then reinterpret this as a
>> big-endian or little-endian float/double/longdouble (returning the
>> native representation), then this can work and is a useful function.
>> Similarly taking a native float/double/longdouble and writing it to a
>> block-of-bytes in a specified endian format.
>
> "Little-endian float" is not enough information. Floating point formats
> are not fully described by their endianness. (Neither are integer
> formats in principle, but in practice they are.)

Do you mean word-granular endianness here? I would say, it's just
another type of endianness.

> Apart from that, I agree. char[4] /* IEEE 32 bit little endian float */
> <-> float is a correct interface. Or even uint32_t <-> float.
>
> uint32_t float_to_bits( float x );
> float float_from_bits( uint32_t v );
>
> If you have that, you can then byteswap the unit32_t to your heart's
> content, even though the correct interface there is also char[4] /*
> little endian 32 bit */ <-> uint32_t.
>
>> As a Boost.Endian library user, until the first style of API is
>> implemented you can work around it by doing endian swaps on unsigned
>> integers only, and using a bitwise_cast-equivalent to convert between
>> the floating-point values and unsigned integers of appropriate size.
>
> Something like that, yes, but what I'm suggesting is not a bitwise cast.
> There need not be any correspondence between the uint32_t bits and the
> float bits, because the uint32_t is IEEE, and the float is native.

I think it's not Boost.Endian's job to deal with FP implementations. Or
integer implementations, for that matter. The interface can be defined
to require a certain implementation of float or to simply ignore the
implementation and consider input as opaque sequence of bytes. The
implementation of that interface should just reorder bytes in that
sequence, as requested, and do nothing more than that.

> Technically, this could also be true for integers; the char[4]
> representation is 32 bit with no padding and no trapping, and the
> uint32_t (which would have to be uint_least32_t) may have them.

uint32_t cannot have traps or padding bits, so no problem there. If the
interface uses this type then it restricts the library to architectures
that can provide such a type, which realistically should be fine, but
probably would not fit the C++ standard.

A more generic interface would just avoid using integers as a storage of
bits and just use a byte buffer for that (i.e. and array of
char/unsigned char/signed char or input/output iterators of such value
type or some such).

> (Although this assumes CHAR_BIT == 8. I'm not sure what is the right
> interface when CHAR_BIT is 32.)

If a raw buffer is used to store bits then there is no problem as any
C++ type has size of an integer number of chars. This may pose
interoperability issues between platforms with different values of
CHAR_BIT, but I'm inclined to think this is not a problem of endianness
per se, but a problem of portable (de)serialization, which is a much
wider problem than just endianness management (which, by definition,
operates whole bytes - which are chars in C++).


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk