Thread overview
DMD OSX / Segfault 11
Feb 02, 2016
Robert M. Münch
Feb 03, 2016
Robert M. Münch
Feb 04, 2016
Robert M. Münch
Feb 02, 2016
anonymous
Feb 03, 2016
Robert M. Münch
Feb 03, 2016
anonymous
Feb 04, 2016
Robert M. Münch
February 02, 2016
I have a very strange effect, I'm not sure what it is about:

Value: {}

WordV: Value {
	Value* get() {}
}

BaseOperator: Value : {
}


Now comes the code using this:

auto op = cast(BaseOperator)(Word.get());
if (op !is null) {...


If get() returns "Value*" it segfaults, if I change it to "Value" it works. How can this be?

I want to check of the Value returned from get() is a BaseOperator or not.

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster

February 02, 2016
On 2/2/16 1:06 PM, Robert M. Münch wrote:
> I have a very strange effect, I'm not sure what it is about:
>
> Value: {}
>
> WordV: Value {
>      Value* get() {}
> }
>
> BaseOperator: Value : {
> }
>
>
> Now comes the code using this:
>
> auto op = cast(BaseOperator)(Word.get());
> if (op !is null) {...
>
>
> If get() returns "Value*" it segfaults, if I change it to "Value" it
> works. How can this be?
>
> I want to check of the Value returned from get() is a BaseOperator or not.
>

If this is valid D, I'm not sure what it means :)

-Steve
February 02, 2016
On 02.02.2016 19:06, Robert M. Münch wrote:
> I have a very strange effect, I'm not sure what it is about:
>
> Value: {}
>
> WordV: Value {
>      Value* get() {}
> }
>
> BaseOperator: Value : {
> }

This isn't valid D code at all, which makes it unnecessarily hard to understand what you mean.

> Now comes the code using this:
>
> auto op = cast(BaseOperator)(Word.get());
> if (op !is null) {...
>
>
> If get() returns "Value*" it segfaults, if I change it to "Value" it
> works. How can this be?

A Value* is a pointer to a class reference. Unless you're doing something really funky with the pointer, casting it to a class type doesn't make sense.

Casting between class types that have an inheritance relation, like Value and BaseOperator, does make sense (upcat/downcast).

If anything, you should be casting between Value* and BaseOperator* (both pointer types) if you want to do something with pointers.

But you very seldom need pointers to class references. Just return Value from get, and cast to BaseOperator.
February 03, 2016
On 2016-02-02 19:03:04 +0000, anonymous said:

> This isn't valid D code at all, which makes it unnecessarily hard to understand what you mean.

Well, it should of course be:

BaseOperator: Value {
}

> A Value* is a pointer to a class reference. Unless you're doing something really funky with the pointer, casting it to a class type doesn't make sense.
> 
> Casting between class types that have an inheritance relation, like Value and BaseOperator, does make sense (upcat/downcast).

Yes, that's what I need.

> If anything, you should be casting between Value* and BaseOperator* (both pointer types) if you want to do something with pointers.

I tried this, but that doesn't work either.

> But you very seldom need pointers to class references. Just return Value from get, and cast to BaseOperator.

But am I not getting a copy then? I want to avoid copying objects as much as possible.

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster

February 03, 2016
On 2016-02-02 18:59:35 +0000, Steven Schveighoffer said:

> If this is valid D, I'm not sure what it means :)

There was one type, the rest I stripped totally away as IMO it's not relevant for the actual problem.

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster

February 03, 2016
On 03.02.2016 14:16, Robert M. Münch wrote:
> Well, it should of course be:
>
> BaseOperator: Value {
> }

Still missing "class". I know I'm being pedantic, but if you're being sloppy here, how do I know that you're not being sloppy where it matters?

>> Casting between class types that have an inheritance relation, like
>> Value and BaseOperator, does make sense (upcat/downcast).
>
> Yes, that's what I need.

Do that then. Cast between class types. Pointers don't by you anything here.

>> If anything, you should be casting between Value* and BaseOperator*
>> (both pointer types) if you want to do something with pointers.
>
> I tried this, but that doesn't work either.

Yeah, you can't check if the downcast succeeded this way. Casts between pointers always succeed (and then fail horribly at run-time).

>> But you very seldom need pointers to class references. Just return
>> Value from get, and cast to BaseOperator.
>
> But am I not getting a copy then? I want to avoid copying objects as
> much as possible.

No, you're not getting a copy. Classes are reference types. That means, variables of class types are references already. They're pointers in disguise.
February 03, 2016
On 2/3/16 8:17 AM, Robert M. Münch wrote:
> On 2016-02-02 18:59:35 +0000, Steven Schveighoffer said:
>
>> If this is valid D, I'm not sure what it means :)
>
> There was one type, the rest I stripped totally away as IMO it's not
> relevant for the actual problem.
>

Very relevant: what are you declaring? A class, struct, template, enum?

-Steve
February 04, 2016
On 2016-02-03 14:35:16 +0000, Steven Schveighoffer said:

> On 2/3/16 8:17 AM, Robert M. Münch wrote:
>> On 2016-02-02 18:59:35 +0000, Steven Schveighoffer said:
>> 
>>> If this is valid D, I'm not sure what it means :)
>> 
>> There was one type, the rest I stripped totally away as IMO it's not
>> relevant for the actual problem.
>> 
> 
> Very relevant: what are you declaring? A class, struct, template, enum?

;-) Ok... that's really missing. A class.

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster

February 04, 2016
On 2016-02-03 13:29:15 +0000, anonymous said:

> Still missing "class". I know I'm being pedantic, but if you're being sloppy here, how do I know that you're not being sloppy where it matters?

You are right, sorry. I was to focused on the problem part...


>>> If anything, you should be casting between Value* and BaseOperator*
>>> (both pointer types) if you want to do something with pointers.
>> 
>> I tried this, but that doesn't work either.
> 
> Yeah, you can't check if the downcast succeeded this way. Casts between pointers always succeed (and then fail horribly at run-time).

Aha, that's my missing link. I didn't know that and it makes it all clear.

IMO that's a not to underestimate trap. Since I can use the . notation instead of -> when using pointers, I would have expected that casting will work the same with both variants as well...

>> But am I not getting a copy then? I want to avoid copying objects as
>> much as possible.
> 
> No, you're not getting a copy. Classes are reference types. That means, variables of class types are references already. They're pointers in disguise.

Ok. Seems I was really confused. Thanks a lot.

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster