D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 3194 - invariant should be checked at the beginning and end of protected functions
Summary: invariant should be checked at the beginning and end of protected functions
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: Other Linux
: P2 normal
Assignee: No Owner
URL:
Keywords: patch
Depends on:
Blocks:
 
Reported: 2009-07-20 14:12 UTC by Andrei Alexandrescu
Modified: 2015-06-09 01:31 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Andrei Alexandrescu 2009-07-20 14:12:56 UTC
Consider:

class A
{
    invariant() { ... }
    public void f() { ... }
    protected void g() { ... }
}

Currently invariant is called at the beginning and end of each public function, the end of the constructor, and the beginning of the destructor. Scott Meyers pointed out to a quite known fact - protected is much closer to public than to private in terms of offering access control. This is because anyone can just inherit from a class and call protected methods, or even wrap them in public methods.

Consequently, it looks like the invariant of a class must also hold upon entry and exit of all protected methods.
Comment 1 yebblies 2011-06-11 12:10:59 UTC
Patch for D2
https://github.com/D-Programming-Language/dmd/pull/112
Comment 2 Diego Canuhe 2011-06-22 11:52:38 UTC
(In reply to comment #1)
> Patch for D2
> https://github.com/D-Programming-Language/dmd/pull/112

I disagree.
Even while you can easily access protected methods of a class, they are intended for internal use, otherwise they'd be public.

Consider:

class A
{
    abstract protected SomeType[] getData();
    
    public void processData()
    {
        //do something that breaks the invariants
        foreach (SomeType element; getData())
        {
            //do something...
        }
        //do something that restores the invariants
    }

    invariant() {...}
}

a class B derived from A implementing getData() shouldn't have to respect the invariants while entering/leaving getData(). Anything regarding getData()'s side-effects should be put in an out clause.

BTW, abstract functions shouldn't require a body clause accompanying in and out clauses