3578 – Impossible to run a struct invariant using assert(s)

D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 3578 - Impossible to run a struct invariant using assert(s)
Summary: Impossible to run a struct invariant using assert(s)
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 normal
Assignee: No Owner
URL:
Keywords: rejects-valid, spec
: 4326 (view as issue list)
Depends on:
Blocks:
Reported: 2009年12月05日 08:24 UTC by Leandro Lucarella
Modified: 2015年06月09日 05:11 UTC (History)
4 users (show)

See Also:


Attachments
Add an attachment (proposed patch, testcase, etc.)

Note You need to log in before you can comment on or make changes to this issue.
Description Leandro Lucarella 2009年12月05日 08:24:54 UTC
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 Leandro Lucarella 2010年06月21日 17:44:13 UTC
*** Issue 4326 has been marked as a duplicate of this issue. ***
Comment 2 Shin Fujishiro 2010年10月16日 12:02:06 UTC
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 Leandro Lucarella 2010年10月16日 16:06:59 UTC
(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.


AltStyle によって変換されたページ (->オリジナル) /