Bug 1228 – Class invariants should not be called before the object is fully constructed

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
Other
OS
Linux
Creation time
2007-05-11T13:04:00Z
Last change time
2014-02-16T15:22:06Z
Assigned to
bugzilla
Creator
onlystupidspamhere

Comments

Comment #0 by onlystupidspamhere — 2007-05-11T13:04:28Z
The spec should state whether invariants hold only after the constructor has finished or not. http://www.webber-labs.com/research/paste01.ps contains some discussion about class invariants in Java, and might be helpful. The following code shows how D currently checks invariants even before the class has been fully constructed. IMO invariants should hold only after the constructor has finished and there is a valid reference to the object. Code: import tango.io.Stdout; class foo { this() { Stdout("entering constructor").newline; bar(); Stdout("leaving constructor").newline; } void bar() { Stdout("method bar()").newline; } invariant { Stdout("invariant").newline; } } void main() { auto a = new foo(); } Output: entering constructor invariant method bar() invariant leaving constructor invariant
Comment #1 by braddr — 2007-05-11T14:25:52Z
Invariants are checked after every public member function's execution as well, so the behavior you're seeing at least meets the spec. Now, I can see some arguments for not having invariants checked until construction is complete, but that'd be a change in documented behavior.
Comment #2 by ary — 2007-05-11T15:10:19Z
Comment #3 by onlystupidspamhere — 2007-05-12T04:11:27Z
(In reply to comment #2) > Sound reasonable to me, too. You can always refactor to: > > class foo { > > this() { > Stdout("entering constructor").newline; > barInternal(); > Stdout("leaving constructor").newline; > } > > void bar() { > barInternal(); > } > > private void barInternal() { > Stdout("method bar()").newline; > } > > invariant { > Stdout("invariant").newline; > } > } This slows down the release build since at least DMD doesn't inline member functions. Yes, this is a design decision and I'm not sure which one is better.
Comment #4 by bugzilla — 2007-07-01T00:38:19Z
Since the invariant is called at the start of public or exported members, such members should not be called from constructors. I'll update the documentation to indicate this.
Comment #5 by onlystupidspamhere — 2007-07-01T03:05:48Z
(In reply to comment #4) > Since the invariant is called at the start of public or > exported members, such members should not be called from > constructors. I'll update the documentation to indicate this. Good, updating the docs works for me.
Comment #6 by bugzilla — 2007-07-01T14:02:41Z
Fixed DMD 1.018 and DMD 2.002