c++language-lawyerprotectedaccess-specifiermember-pointers

Access to protected member through member-pointer: is it a hack?


We all know members specified protected from a base class can only be accessed from a derived class own instance. This is a feature from the Standard, and this has been discussed on Stack Overflow multiple times:

But it seems possible to walk around this restriction with member pointers, as user chtz has shown me:

struct Base { protected: int value; };
struct Derived : Base
{
    void f(Base const& other)
    {
        //int n = other.value; // error: 'int Base::value' is protected within this context
        int n = other.*(&Derived::value); // ok??? why?
        (void) n;
    }
};

Live demo on coliru

Why is this possible, is it a wanted feature or a glitch somewhere in the implementation or the wording of the Standard?


From comments emerged another question: if Derived::f is called with an actual Base, is it undefined behaviour?


Solution

  • The fact that a member is not accessible using class member access expr.ref (aclass.amember) due to access control [class.access] does not make this member inaccessible using other expressions.

    The expression &Derived::value (whose type is int Base::*) is perfectly standard compliant, and it designates the member value of Base. Then the expression a_base.*p where p is a pointer to a member of Base and a_base an instance of Base is also standard compliant.

    So any standard compliant compiler shall make the expression other.*(&Derived::value); defined behavior: access the member value of other.