Re: segfault in invariant { assert(super); }

2015-12-22 Thread SimonN via Digitalmars-d-learn
On Monday, 21 December 2015 at 20:29:14 UTC, Steven Schveighoffer 
wrote:

1) Is this recursion expected?
Yes. assert calls the virtual invariant function, which in the 
case of super is equivalent to this. So you are essentially 
calling assert(this).



2) The example is a dustmite'd version of this:
It seems like something you shouldn't do. AFAIK, invariant 
should not call any public functions on your existing class.


Thanks for the reply! Yeah, this helps for a clearer picture of 
what's happening.


In particular, even though all invariants of a class hierarchy 
are tested instead of only the most-subclassed-one, triggering 
the invariant check remains virtual. I didn't know that.


Even if Base.f() is const, it's not allowed inside 
Derived.invariant(). This is again understandable: By OOP 
principles, Derived shouldn't impose further restrictions on Base 
than what Base imposes on itself already.



(good idea to file an enhancement report).


For that, I was trying earlier today to find the exact instances 
of when there is a warning, and when there is not. I didn't get 
warnings to come up consistently. (Even the case I described in 
question 2 doens't always give a warning.) I'd have to take a 
look at this some time again.


-- Simon


Re: segfault in invariant { assert(super); }

2015-12-21 Thread Steven Schveighoffer via Digitalmars-d-learn

On 12/19/15 11:01 PM, SimonN wrote:

Hi,

the following code compiles fine, then segfaults upon running.

 class Base {
 this(int) { }
 }

 class Derived : Base {
 this(int a) { super(a); }
 invariant() { assert (super); }
 }

 void main()
 {
 new Derived(5);
 }

Tested both with dmd 2.069.2 on Linux 64-bit, and on dpaste's dmd 2.069.1:

 http://dpaste.dzfl.pl/4b9475c668f1

Backtrace on my home machine:

 Program received signal SIGSEGV, Segmentation fault.
 0x004246a5 in _D9invariant12_d_invariantFC6ObjectZv ()
 (gdb) bt
 #0  0x004246a5 in _D9invariant12_d_invariantFC6ObjectZv ()
 #1  0x00647bf0 in _D3app7Derived6__initZ ()
 #2  0x7f7ff030 in ?? ()
 #3  0x0042301f in _D3app7Derived12__invariant1MxFZv (this=0x0)
 at source/app.d:7
 Backtrace stopped: previous frame inner to this frame (corrupt stack?)

So, looks like endless recursion inside the invairant.

Questions:

1) Is this recursion expected?


Yes. assert calls the virtual invariant function, which in the case of 
super is equivalent to this. So you are essentially calling assert(this).



2) The example is a dustmite'd version of this: I have a public final
method Base.f(), and the compiler won't let me call f() in Derived's
invariant. This is understandable, because f() is also a public method
of Derived. However, I can call super.f() explicitly in Derived's
invariant, with no compiler error. Is that expected to work, or should
it lead to a similar segfault? (I get the segfault.)


It seems like something you shouldn't do. AFAIK, invariant should not 
call any public functions on your existing class. It would make sense 
that super.f() should be disallowed if f() is disallowed (good idea to 
file an enhancement report).


But the compiler can't prevent all issues here. All you need to do is 
obscure that the object you are asserting is 'this', and you can achieve 
the behavior.


The runtime could potentially use a gate to prevent recursive calls, 
though I think the compiler would have to do this.


-Steve


segfault in invariant { assert(super); }

2015-12-19 Thread SimonN via Digitalmars-d-learn

Hi,

the following code compiles fine, then segfaults upon running.

class Base {
this(int) { }
}

class Derived : Base {
this(int a) { super(a); }
invariant() { assert (super); }
}

void main()
{
new Derived(5);
}

Tested both with dmd 2.069.2 on Linux 64-bit, and on dpaste's dmd 
2.069.1:


http://dpaste.dzfl.pl/4b9475c668f1

Backtrace on my home machine:

Program received signal SIGSEGV, Segmentation fault.
0x004246a5 in _D9invariant12_d_invariantFC6ObjectZv ()
(gdb) bt
#0  0x004246a5 in 
_D9invariant12_d_invariantFC6ObjectZv ()

#1  0x00647bf0 in _D3app7Derived6__initZ ()
#2  0x7f7ff030 in ?? ()
#3  0x0042301f in _D3app7Derived12__invariant1MxFZv 
(this=0x0)

at source/app.d:7
Backtrace stopped: previous frame inner to this frame 
(corrupt stack?)


So, looks like endless recursion inside the invairant.

Questions:

1) Is this recursion expected?

2) The example is a dustmite'd version of this: I have a public 
final method Base.f(), and the compiler won't let me call f() in 
Derived's invariant. This is understandable, because f() is also 
a public method of Derived. However, I can call super.f() 
explicitly in Derived's invariant, with no compiler error. Is 
that expected to work, or should it lead to a similar segfault? 
(I get the segfault.)


-- Simon