Jump to page: 1 2
Thread overview
Casting Pointers?
May 12, 2016
John Burton
May 12, 2016
ZombineDev
May 12, 2016
Stefan Koch
May 12, 2016
Rene Zwanenburg
May 12, 2016
John Burton
May 12, 2016
Rene Zwanenburg
May 12, 2016
Marco Leise
May 13, 2016
Rene Zwanenburg
May 12, 2016
Dicebot
May 12, 2016
Dicebot
May 12, 2016
H. S. Teoh
May 12, 2016
Dicebot
May 12, 2016
Johannes Pfau
May 12, 2016
H. S. Teoh
May 12, 2016
Anon
May 12, 2016
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
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
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
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
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
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
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
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
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
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.
« First   ‹ Prev
1 2