December 11, 2003
I was expecting this to work:

----------------a.d----------------
class A { protected int a; }
----------------b.d----------------
import std.c.stdio;
import a;

class B : A {
 void print(A a) {
  printf("%d\n",a.a);  //here
 }
}
----------------c.d----------------
import b;

void main() {
 (new B).print(new A);
}
-----------------------------------

But instead I get "b.d(6): class A member a is not accessible". I'd call it a bug, but it might be feature. If it is a feature, why is that?

-------------------------
Carlos Santander


---

Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.550 / Virus Database: 342 - Release Date: 2003-12-09


December 11, 2003
In article <br8cad$2a47$1@digitaldaemon.com>, Carlos Santander B. wrote:
> I was expecting this to work:
> 
> ----------------a.d----------------
> class A { protected int a; }
> ----------------b.d----------------
> import std.c.stdio;
> import a;
> 
> class B : A {
>  void print(A a) {
>   printf("%d\n",a.a);  //here
>  }
> }
> ----------------c.d----------------
> import b;
> 
> void main() {
>  (new B).print(new A);
> }
> -----------------------------------
> 
> But instead I get "b.d(6): class A member a is not accessible". I'd call it a bug, but it might be feature. If it is a feature, why is that?

I noticed the same thing in C++ -- namely that protected access restrictions can be bypassed only when accessing from the deriving object itself, not outside it.

Which is kind of inconsistent because private access restrictions are controlled on class level, instead of the object level. But on the other hand, it's kind of logical: that the A object in question might not be a B, or even another type derived from A. Or it could be another type that does not expect that _anyone_ can access its member a except itself:

class A { protected int a; }

class B : A
{
    void betray(A a)
    {
        a.a = 5;
    }
}

class C : A
{
    void gullible(B traitor)
    {
        a = 1;
        // In good faith we give our destiny into its hands
        traitor.betray(this);
        assert(a == 1); // crash! who changed my A?
    }
}

int main()
{
    B b = new B;
    C c = new C;

    c.gullible(b);
}

(Warning - The code is untested. DMD doesn't work with my Linux box because it appears to be compiled with an older libc/gcc and I don't have any older libraries for compatibility)

-Antti