Bug 24149 – Improve invariant checking with assert

Status
NEW
Severity
enhancement
Priority
P5
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2023-09-18T15:03:23Z
Last change time
2024-12-13T19:30:52Z
Assigned to
No Owner
Creator
Bolpat
Moved to GitHub: dmd#20333 →

Comments

Comment #0 by qs.il.paperinik — 2023-09-18T15:03:23Z
One can explicitly run (“check”) invariants of aggregates using a reference (pointer to struct/union type, object handle of a class) as the argument of an `assert` statement. This is an bad feature: It looks like something that it isn’t, namely (merely) checking if the reference is `null`. In almost all cases one encounters `assert` (reading or writing), it asserts that a boolean condition is true, and a reference is a boolean condition: `if (r)` is equivalent to `if (r !is null)`. While opinions may differ if leaving `!is null` implicit is good or bad style, it certainly is widely known and understood. However, `assert` weirdly special-cases references and using `!is null` is *required* if mere `null` checking is desired. I suggest a new construct to check invariants: The `invariant` keyword after `assert`, such that it is patently obvious what the intent is and what happens: ```d Class c = …; assert(c); // deprecated assert(c !is null); // Step 1 assert invariant(c); // Step 2 Struct s; assert(&s); // deprecated assert invariant(s); ``` For class handles, where the `assert` checking for `null` really means something, the fact that `assert` does two (quite different) things is clearly expressed and (by context) unneeded steps can be left out. Of course, `assert invariant` can only be used with an aggregate value is passed to it. It differs from `assert` in that structs/union objects are not passed to it by pointer, but “normally”. Also, it does not perform a `null` check, but requires that the reference is not `null`. Alternatively, `invariant(s)` can be made a primary expression that executes the invariants and evaluates to `true`; then, uses of `assert` to check invariants can state intent properly: ```d Class c = …; assert(c); // deprecated assert(c && invariant(c)); // okay assert(c !is null && invariant(c)); // good Struct s = …; assert(&s); // deprecated assert(invariant(s)); // good ```
Comment #1 by robert.schadek — 2024-12-13T19:30:52Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/20333 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB