The struct C is nested inside class B, it's regared as a member so it has the same access rights as any other member. So yes it could access the protected members of the base class A. But note that you could only access the protected members of A through an object of type B; you can't do that through a A. That makes sense, because the members of derived class should only be possible to access the protected members inherited from the base class; these members belong to the derived class. But accessing the protected members of the base class directly should not be allowed; they belong to the base class (or the other derived class).
The rule is not special for the inner class, it's also true for the member functions of B.
§11.4/1 Protected member access [class.protected]
(emphasis mine)
An additional access check beyond those described earlier in Clause
[class.access] is applied when a non-static data member or non-static
member function is a protected member of its naming class
([class.access.base])115 As described earlier, access to a protected
member is granted because the reference occurs in a friend or member
of some class C. If the access is to form a pointer to member
([expr.unary.op]), the nested-name-specifier shall denote C or a class
derived from C. All other accesses involve a (possibly implicit)
object expression ([expr.ref]). In this case, the class of the object
expression shall be C or a class derived from C. [ Example:
class B {
protected:
int i;
static int j;
};
class D1 : public B {
};
class D2 : public B {
friend void fr(B*,D1*,D2*);
void mem(B*,D1*);
};
...
void D2::mem(B* pb, D1* p1) {
pb->i = 1; // ill-formed
p1->i = 2; // ill-formed
i = 3; // OK (access through this)
B::i = 4; // OK (access through this, qualification ignored)
int B::* pmi_B = &B::i; // ill-formed
int B::* pmi_B2 = &D2::i; // OK
j = 5; // OK (because j refers to static member)
B::j = 6; // OK (because B::j refers to static member)
}
...
— end example ]