Bug 3578 – Impossible to run a struct invariant using assert(s)
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2009-12-05T08:24:00Z
Last change time
2015-06-09T05:11:47Z
Keywords
rejects-valid, spec
Assigned to
nobody
Creator
leandro.lucarella
Comments
Comment #0 by leandro.lucarella — 2009-12-05T08:24:54Z
This fails to compile (with -unittest):
---
struct S {
invariant() { assert (false); }
unittest { S s; assert (s); }
}
---
With this error message:
inv.d(3): Error: expression s of type S does not have a boolean value
With both DMD 1 and 2 (tested with DMD 1.041 and DMD 2.037. Changing struct to class compiles fine (and dumps a core if you run it, of course ;).
Thes specs are not clear on this in both D1 and D2. Invariant is only mentioned in structs, but I guess it's more likely to think that the description of class invariant apply to structs too, so I guess this should be supported in both D1 and D2.
If it's a change to big to make it in D1, I think the specs should be updated to clarify the differences between struct and class invariants. In D2 I don't see why the language should not be updated to support this, since there is no other way to trigger an invariant check (and, for example, invariant is not executed when a struct is constructed or when using alias this, I think).
Comment #1 by leandro.lucarella — 2010-06-21T17:44:13Z
*** Issue 4326 has been marked as a duplicate of this issue. ***
Comment #2 by rsinfu — 2010-10-16T12:02:06Z
It's undocumented, but struct invariants are fired on pointers:
--------------------
struct S
{
invariant() { assert(0); } // (3)
}
void main()
{
S s;
assert(&s);
}
--------------------
% dmd -run test.d
core.exception.AssertError@test(3): Assertion failure
--------------------
Though it's non-intuitive, I find it reasonable considering that structs can define opCast to bool. assert(s) would be ambiguous if s had both invariant and opCast!bool.
Comment #3 by leandro.lucarella — 2010-10-16T16:06:59Z
(In reply to comment #2)
> It's undocumented, but struct invariants are fired on pointers:
> --------------------
> struct S
> {
> invariant() { assert(0); } // (3)
> }
> void main()
> {
> S s;
> assert(&s);
> }
> --------------------
> % dmd -run test.d
> core.exception.AssertError@test(3): Assertion failure
> --------------------
>
> Though it's non-intuitive, I find it reasonable considering that structs can
> define opCast to bool. assert(s) would be ambiguous if s had both invariant
> and opCast!bool.
I never expected that, but it makes sense as you mention.
I guess this behavior should be documented in the specs.
Comment #4 by github-bugzilla — 2012-01-23T01:50:33Z