| Thread overview | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 12, 2016 Casting Pointers? | ||||
|---|---|---|---|---|
| ||||
I've been unable to find a clear definitive answer to this so please point me to one if it already exists in the manual or the forums.
Is it safe to cast pointer types?
double data;
long p = *cast(long*)&data;
(Excuse any silly syntax errors as I'm doing this on my phone).
This used to be possible in C until people recently decided it not only was wrong, it had always been wrong :P (Ok I'm not entirely serious there but that's what this issue feels like...)
Is this legal / valid in D and if not what is the appropriate way to efficiently access data like this?
| ||||
May 12, 2016 Re: Casting Pointers? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to John Burton | On Thursday, 12 May 2016 at 08:41:25 UTC, John Burton wrote: > I've been unable to find a clear definitive answer to this so please point me to one if it already exists in the manual or the forums. > > Is it safe to cast pointer types? > > double data; > long p = *cast(long*)&data; > > (Excuse any silly syntax errors as I'm doing this on my phone). > > This used to be possible in C until people recently decided it not only was wrong, it had always been wrong :P (Ok I'm not entirely serious there but that's what this issue feels like...) > > Is this legal / valid in D and if not what is the appropriate way to efficiently access data like this? Yes, it's perfectly legal in @system code, but only if you know what you're doing ;) Take a look at std.math for example: https://github.com/dlang/phobos/blob/v2.071.0/std/math.d#L4839 | |||
May 12, 2016 Re: Casting Pointers? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to John Burton | On Thursday, 12 May 2016 at 08:41:25 UTC, John Burton wrote:
> I've been unable to find a clear definitive answer to this so please point me to one if it already exists in the manual or the forums.
>
> Is it safe to cast pointer types?
>
> double data;
> long p = *cast(long*)&data;
>
> (Excuse any silly syntax errors as I'm doing this on my phone).
>
> This used to be possible in C until people recently decided it not only was wrong, it had always been wrong :P (Ok I'm not entirely serious there but that's what this issue feels like...)
>
> Is this legal / valid in D and if not what is the appropriate way to efficiently access data like this?
How would such a cast be safe?
| |||
May 12, 2016 Re: Casting Pointers? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to John Burton | On Thursday, 12 May 2016 at 08:41:25 UTC, John Burton wrote:
> Is this legal / valid in D and if not what is the appropriate way to efficiently access data like this?
Phobos / druntime use casts like this as well, but there has been some discussion as to whether it should be guaranteed to be correct. There are good reasons the C folks disallow it (well, performance of course, what else? ^^), and the reasoning applies to D as well.
In this case, you can use a union:
union DL
{
double d;
long l;
}
auto dl = DL(1.0);
writeln(dl.l);
| |||
May 12, 2016 Re: Casting Pointers? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | On Thursday, 12 May 2016 at 09:25:49 UTC, Stefan Koch wrote:
> How would such a cast be safe?
I'm guessing safe as in defined behavior.
| |||
May 12, 2016 Re: Casting Pointers? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to John Burton | On Thursday, 12 May 2016 at 08:41:25 UTC, John Burton wrote:
> Is this legal / valid in D and if not what is the appropriate way to efficiently access data like this?
We rely on this cast to be legal and well-defined in a lot of Sociomantic code, banning would be a real disaster :X
| |||
May 12, 2016 Re: Casting Pointers? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Thursday, 12 May 2016 at 09:33:54 UTC, Dicebot wrote:
> On Thursday, 12 May 2016 at 08:41:25 UTC, John Burton wrote:
>> Is this legal / valid in D and if not what is the appropriate way to efficiently access data like this?
>
> We rely on this cast to be legal and well-defined in a lot of Sociomantic code, banning would be a real disaster :X
(most common case is casting between `char[]` and `struct S { char[]; }`)
| |||
May 12, 2016 Re: Casting Pointers? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | On Thursday, 12 May 2016 at 09:25:49 UTC, Stefan Koch wrote:
> On Thursday, 12 May 2016 at 08:41:25 UTC, John Burton wrote:
>> I've been unable to find a clear definitive answer to this so please point me to one if it already exists in the manual or the forums.
>>
>> Is it safe to cast pointer types?
>>
>> double data;
>> long p = *cast(long*)&data;
>>
>> (Excuse any silly syntax errors as I'm doing this on my phone).
>>
>> This used to be possible in C until people recently decided it not only was wrong, it had always been wrong :P (Ok I'm not entirely serious there but that's what this issue feels like...)
>>
>> Is this legal / valid in D and if not what is the appropriate way to efficiently access data like this?
>
> How would such a cast be safe?
"Safe" as in it produces a valid long value by interpreting the bytes of the stored double. Obviously if it works it's very system dependent.
But in C it's simply undefined behavior to read a value stored using one pointer type using a pointer to a different type. (With some additional rules about char in a few cases).
The whole strict aliasing businesss
| |||
May 12, 2016 Re: Casting Pointers? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to John Burton | On Thu, May 12, 2016 at 08:41:25AM +0000, John Burton via Digitalmars-d wrote: > I've been unable to find a clear definitive answer to this so please point me to one if it already exists in the manual or the forums. > > Is it safe to cast pointer types? > > double data; > long p = *cast(long*)&data; > > (Excuse any silly syntax errors as I'm doing this on my phone). > > This used to be possible in C until people recently decided it not only was wrong, it had always been wrong :P (Ok I'm not entirely serious there but that's what this issue feels like...) > > Is this legal / valid in D and if not what is the appropriate way to efficiently access data like this? AFAIK this is legal in D, though it does break @safe-ty so it can only be used in @system code. An alternative is to use a union: long reinterpretAsLong(double data) @safe { union U { double d; long l; } U u; u.d = data; return u.l; } A bit verbose, but disassembly shows that the dmd -O is able to reduce it to a single mov instruction, as it should be. T -- English is useful because it is a mess. Since English is a mess, it maps well onto the problem space, which is also a mess, which we call reality. Similarly, Perl was designed to be a mess, though in the nicest of all possible ways. -- Larry Wall | |||
May 12, 2016 Re: Casting Pointers? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Thu, May 12, 2016 at 09:38:27AM +0000, Dicebot via Digitalmars-d wrote: > On Thursday, 12 May 2016 at 09:33:54 UTC, Dicebot wrote: [...] > >We rely on this cast to be legal and well-defined in a lot of Sociomantic code, banning would be a real disaster :X > > (most common case is casting between `char[]` and `struct S { char[]; }`) Does alias this solve the problem, or it introduces new ones? T -- Let's eat some disquits while we format the biskettes. | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply