Bug 13710 – Invariants not enforced on methods from alias this
Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-11-11T07:20:00Z
Last change time
2014-11-11T14:29:27Z
Assigned to
nobody
Creator
markisaa
Comments
Comment #0 by markisaa — 2014-11-11T07:20:20Z
When you do "alias this" and have an invariant, any
methods that are forwarded to the aliased member do not invoke
your invariant methods.
This prevents me from writing a really sleek 10-liner to the tune
of:
struct ValueRestrictedInteger(int lowerBound, int upperBound) {
int value;
alias value this;
this (int rhs) { value = rhs; }
invariant() {
assert (value >= lowerBound && value <= upperBound);
}
void forDemonstrationOnly() {}
}
unittest {
ValueRestrictedInteger!(0, 100) x = 0;
x += 10;
x -= 100; //This works, but I don't think it should
x.forDemonstrationOnly(); //This causes the assertion to fire
ValueRestrictedInteger!(0, 100) y = -100; //This also would hit
the assertion
}
Forum post on same topic: http://forum.dlang.org/thread/[email protected]
Comment #1 by schveiguy — 2014-11-11T13:10:46Z
I think from angel's comment that discussion, this bug is invalid. There is no method to call, so it cannot hook the invariant, x -= 100 translates directly to machine instructions.
What I would suggest is instead of using alias this, use opDispatch and opBinary to implement inlined functions that forward to the member. Then your invariant will be called. Instead of using alias this for inheritance, use composition.
Comment #2 by clugdbug — 2014-11-11T14:16:33Z
I think there is still a problem. Does it actually make sense to have a class invariant, when you have an alias this?
It seems as though having an 'alias this' is like exposing a public member variable: once you do this, the class invariant cannot be trusted to be true at all times.
I feel uneasy about this; it suggests that 'alias this' is bad practice.
It may be worth adding to the documentation at
http://dlang.org/contracts.
That states:
"Invariants are used to specify characteristics of a class or struct that always must be true (except while executing a member function)."
I think that section should explicitly state that direct modification of members in a way which violates the invariant, will not be detected until a member function is called.
Comment #3 by schveiguy — 2014-11-11T14:29:27Z
It's not just with alias this. Any modification of a member variable outside using the methods can result in breaking the invariant.
I think it's not a bad idea to mention the pitfalls, but I don't think alias this is special in that regard.