Thread overview
Converting a ulong to a byte array and constructing a ulong from it
Oct 24, 2019
9898287
Oct 24, 2019
Paul Backus
Oct 24, 2019
9898287
Oct 24, 2019
Paul Backus
Oct 24, 2019
welkam
Oct 24, 2019
Radu
Oct 24, 2019
Daniel Kozak
October 24, 2019
What's the function for converting a ulong to a native-endian byte array?
For example,

auto bytes = 0x1234567890123456u64.to_ne_bytes();
// should yield
// [0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56] in big-endian and
// [0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12] in little-endian systems

Also, what's the function for constructing a ulong from a native-endian byte array?
For example,

auto value = from_be_bytes!ulong([0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]);
// value is 0x1234567890123456

Rust equivalent:
https://doc.rust-lang.org/std/primitive.u64.html#method.to_ne_bytes
October 24, 2019
On Thursday, 24 October 2019 at 13:33:30 UTC, 9898287 wrote:
> What's the function for converting a ulong to a native-endian byte array?
> For example,
>
> auto bytes = 0x1234567890123456u64.to_ne_bytes();
> // should yield
> // [0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56] in big-endian and
> // [0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12] in little-endian systems
>
> Also, what's the function for constructing a ulong from a native-endian byte array?
> For example,
>
> auto value = from_be_bytes!ulong([0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]);
> // value is 0x1234567890123456
>
> Rust equivalent:
> https://doc.rust-lang.org/std/primitive.u64.html#method.to_ne_bytes

Use a cast:

    ulong n = 0x1122334455667788;
    ubyte[] bytes = (cast(ubyte*) &n)[0 .. n.sizeof];
    ulong m = *cast(ulong*) bytes.ptr;
    assert(m == n);

Note that if you're writing code that cares about the native byte order, there's a good chance you're making a mistake. Rob Pike has written a blog post titled "The byte order fallacy" discussing this in more detail:

    https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html

If you need to convert between native byte order and big/little endian byte arrays (e.g., for serialization/deserialization), there are functions in `std.bitmanip` that you can use:

    https://dlang.org/phobos/std_bitmanip.html
October 24, 2019
On Thursday, 24 October 2019 at 13:50:54 UTC, Paul Backus wrote:
> On Thursday, 24 October 2019 at 13:33:30 UTC, 9898287 wrote:
>> What's the function for converting a ulong to a native-endian byte array?
>> For example,
>>
>> auto bytes = 0x1234567890123456u64.to_ne_bytes();
>> // should yield
>> // [0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56] in big-endian and
>> // [0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12] in little-endian systems
>>
>> Also, what's the function for constructing a ulong from a native-endian byte array?
>> For example,
>>
>> auto value = from_be_bytes!ulong([0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]);
>> // value is 0x1234567890123456
>>
>> Rust equivalent:
>> https://doc.rust-lang.org/std/primitive.u64.html#method.to_ne_bytes
>
> Use a cast:
>
>     ulong m = *cast(ulong*) bytes.ptr;

Does this contain any undefined behavior? It is in C as far as I knew.



October 24, 2019
On Thursday, 24 October 2019 at 13:33:30 UTC, 9898287 wrote:
> What's the function for converting a ulong to a native-endian byte array?
> For example,
>
> auto bytes = 0x1234567890123456u64.to_ne_bytes();
> // should yield
> // [0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56] in big-endian and
> // [0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12] in little-endian systems
>
> Also, what's the function for constructing a ulong from a native-endian byte array?
> For example,
>
> auto value = from_be_bytes!ulong([0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]);
> // value is 0x1234567890123456
>
> Rust equivalent:
> https://doc.rust-lang.org/std/primitive.u64.html#method.to_ne_bytes

https://dlang.org/phobos/std_bitmanip.html#bigEndianToNative
https://dlang.org/phobos/std_bitmanip.html#nativeToLittleEndian
October 24, 2019
On Thu, Oct 24, 2019 at 3:35 PM 9898287 via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote:
>
> What's the function for converting a ulong to a native-endian
> byte array?
> For example,
>
> auto bytes = 0x1234567890123456u64.to_ne_bytes();
> // should yield
> // [0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56] in big-endian
> and
> // [0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12] in
> little-endian systems
>
> Also, what's the function for constructing a ulong from a
> native-endian byte array?
> For example,
>
> auto value = from_be_bytes!ulong([0x12, 0x34, 0x56, 0x78, 0x90,
> 0x12, 0x34, 0x56]);
> // value is 0x1234567890123456
>
> Rust equivalent: https://doc.rust-lang.org/std/primitive.u64.html#method.to_ne_bytes

You could use

https://dlang.org/phobos/std_bitmanip.html#write https://dlang.org/phobos/std_bitmanip.html#read
October 24, 2019
On Thursday, 24 October 2019 at 14:08:36 UTC, 9898287 wrote:
> On Thursday, 24 October 2019 at 13:50:54 UTC, Paul Backus wrote:
>> Use a cast:
>>
>>     ulong m = *cast(ulong*) bytes.ptr;
>
> Does this contain any undefined behavior? It is in C as far as I knew.

The equivalent code in C would use a char*, and char is allowed by the C standard to alias any other type [1], so it would not be undefined behavior.

The D language standard is less precise about this sort of thing, so it's hard to say with complete certainty, but the section on casting [2] doesn't mention anything about undefined behavior or strict aliasing, so it's probably fine. (It is, however, forbidden in @safe functions.)

[1] http://port70.net/~nsz/c/c99/n1256.html#6.5p7
[2] https://dlang.org/spec/expression.html#cast_expressions
October 24, 2019
On Thursday, 24 October 2019 at 14:08:36 UTC, 9898287 wrote:
> Does this contain any undefined behavior? It is in C as far as I knew.

immutable int number = 1;
auto bad_idea = (cast(ubyte*) &number)[0 .. number.sizeof];
bad_idea[0] = 2;
writeln(number); //1
writeln(*(cast(int*)bad_idea.ptr)); //2

Cast is a powerful tool and with it you can destroy all type systems guarantees. In your case you will not have any problems just stay away from const and immutable