I have a problem where I'm not sure whether it is my code or one of my
compilers. The design involves two classes, one of which is registered
inside the other, so in the destructor it has to unregister. Further, that
class is just a handle to a ref-counted body, so it is actually the body
that has to unregister when destroyed.
Now, unregistering is a private function, so the handle has to be a friend
in order to access that function. However, different compilers disagree
whether the nested body class also has access to the private function.
I have boiled the code down to these lines here.
class X;
class Y {
friend class X;
static void private_function();
};
class X {
class nested {
nested() {
Y::private_function();
}
};
};
Currently, I have the following opinions:
GCC 4.2 for x86 - okay
MSVC8 for x86 - okay
MSVC8 for ARM - not okay
MSVC8 for MIPS - not okay
So, where is the bug?
Thanks!
Uli
--
Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
It depends whether your compiler implements C++98 or C++03. As of the
later date a nested class is a full member of the enclosing class and so
has full access rights to the private parts of the enclosing class. The
problem you touch on is one of the reasons for the change. Friendship is
NOT transitive but member access is.
--
To my utter surprise this compiled with Comeau Online, which indicates that it's
formally correct (I never thought of C++ friendship working in this way).
> Currently, I have the following opinions:
>
> GCC 4.2 for x86 - okay
> MSVC8 for x86 - okay
> MSVC8 for ARM - not okay
> MSVC8 for MIPS - not okay
>
>
> So, where is the bug?
Apparently with MSVC8.
A practical solution is to let X::nested::nested call X::private_function which
then forwards to Y::private_function.
Cheers & hth.,
- Alf
--
11.4/2: [...]. However, the declarations of members of classes nested
within the friend class cannot access the names of private and
protected members from the class granting friendship. [...]
In the current draft, the whole paragraph reads as
11.4/2: Declaring a class to be a friend implies that the names of
private and protected members from the class granting friendship can
be accessed in the base-specifiers and member declarations of the
befriended class.
It doesn't - at least not in C++2003.
> > So, where is the bug?
>
> Apparently with MSVC8.
No. The change that grants nested classes access to the enclosing
class's friends never made it into the 2003 C++ Standard (although it
is present in the current C++ draft). Therefore, according to the
current C++ Standard:
"The members of a nested class have no special access to members of an
enclosing class, nor to classes or functions that have granted
friendship to an enclosing class; the usual access rules shall be
obeyed." [�11.8/1]
So the "nested" class should not have access to Y::private_function().
Greg
I am absolutely certain we changed that as the Standard also prohibits
an outer class from granting friendship to an inner class. That was
clearly a defect and the response was to grant nested classes full
membership rights.