www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - DMD OSX / Segfault 11

reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
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
Feb 02 2016
next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
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
Feb 02 2016
parent reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
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
Feb 03 2016
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
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
Feb 03 2016
parent =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
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
Feb 04 2016
prev sibling parent reply anonymous <anonymous example.com> writes:
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.
Feb 02 2016
parent reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
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
Feb 03 2016
parent reply anonymous <anonymous example.com> writes:
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.
Feb 03 2016
parent =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
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
Feb 04 2016