Thread overview
Casting pointers
Aug 26, 2015
John Burton
Aug 26, 2015
anonymous
Aug 27, 2015
John Burton
Aug 27, 2015
Gary Willoughby
August 26, 2015
This would be undefined behavior in c++ due to aliasing rules on pointers. It appears to "work" reliably in D when I try it, but that's obviously no guarantee that it's correct or will continue to do so.

Is this correct code in D? And if not, what should I do instead to cleanly and efficiently extract structured data from a sequence of bytes?

import std.stdio;

struct data
{
    int a;
    int b;
}

void main()
{
    byte[] x = [1, 2, 3, 4, 5, 6, 7, 8];

    data* ptr = cast(data*)(x);
    printf("%x %x\n", ptr.a, ptr.b);

}
August 26, 2015
On Wednesday 26 August 2015 14:14, John Burton wrote:

> This would be undefined behavior in c++ due to aliasing rules on pointers. It appears to "work" reliably in D when I try it, but that's obviously no guarantee that it's correct or will continue to do so.
> 
> Is this correct code in D? And if not, what should I do instead to cleanly and efficiently extract structured data from a sequence of bytes?
> 
> import std.stdio;
> 
> struct data
> {
>      int a;
>      int b;
> }
> 
> void main()
> {
>      byte[] x = [1, 2, 3, 4, 5, 6, 7, 8];
> 
>      data* ptr = cast(data*)(x);
>      printf("%x %x\n", ptr.a, ptr.b);
> 
> }

There's an open issue about it: https://issues.dlang.org/show_bug.cgi?id=10750

I don't know where we stand exactly, but by the looks of it, strict aliasing has never been added to the spec. So compilers should not assume it.

As David Nadlinger points out: "There is already quite a lot of D code out there that violates the C-style strict aliasing rules."

I think that code should be fine for now. If it isn't, we have a problem, because with a silent spec we have no way of knowing what alternatives should work.
August 27, 2015
Ok thank you.

Seems to me that there is enough doubt that this is "supported" that I'd be best to avoid relying on it, or at least ensure that it's all encapsulated in something I can easily change.
August 27, 2015
On Wednesday, 26 August 2015 at 12:14:54 UTC, John Burton wrote:
> This would be undefined behavior in c++ due to aliasing rules on pointers. It appears to "work" reliably in D when I try it, but that's obviously no guarantee that it's correct or will continue to do so.
>
> Is this correct code in D? And if not, what should I do instead to cleanly and efficiently extract structured data from a sequence of bytes?
>
> import std.stdio;
>
> struct data
> {
>     int a;
>     int b;
> }
>
> void main()
> {
>     byte[] x = [1, 2, 3, 4, 5, 6, 7, 8];
>
>     data* ptr = cast(data*)(x);
>     printf("%x %x\n", ptr.a, ptr.b);
>
> }

This would perhaps be safer:

import std.stdio;

struct Data
{
    int a;
    int b;
}

void main()
{
    byte[] x = [1, 2, 3, 4, 5, 6, 7, 8];

    Data* data = cast(Data*)(x[0..Data.sizeof].ptr);
    printf("%x %x\n", data.a, data.b);
}
August 27, 2015
On 8/26/15 8:14 AM, John Burton wrote:
> This would be undefined behavior in c++ due to aliasing rules on
> pointers. It appears to "work" reliably in D when I try it, but that's
> obviously no guarantee that it's correct or will continue to do so.
>
> Is this correct code in D? And if not, what should I do instead to
> cleanly and efficiently extract structured data from a sequence of bytes?
>
> import std.stdio;
>
> struct data
> {
>      int a;
>      int b;
> }
>
> void main()
> {
>      byte[] x = [1, 2, 3, 4, 5, 6, 7, 8];
>
>      data* ptr = cast(data*)(x);
>      printf("%x %x\n", ptr.a, ptr.b);
>
> }

This should be defined behavior (but there is an issue that will probably eventually be fixed -- you shouldn't cast an array to a pointer, use x.ptr instead). I think strict aliasing only comes into play when something is *changed*. For example:

byte[] x = [1, 2, 3, 4, 5, 6, 7, 8];

data* ptr = cast(data *)(x.ptr);
ptr.a = 4;
writefln("%x %x\n", x[0], x[1]);


However, if we consider the strict aliasing rule from C++ allows casting to char * and unsigned char *, D's byte[] and ubyte[] should be equivalent to those. So if anything, that should be defined.

-Steve