Re: segfault in invariant { assert(super); }
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); }
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); }
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