Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
August 26, 2015 Casting pointers | ||||
---|---|---|---|---|
| ||||
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 Re: Casting pointers | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Burton | 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 Re: Casting pointers | ||||
---|---|---|---|---|
| ||||
Posted in reply to anonymous | 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 Re: Casting pointers | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Burton | 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 Re: Casting pointers | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Burton | 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
|
Copyright © 1999-2021 by the D Language Foundation