Topic: Long distance friendship problem w/o ODR violation?
Author: wmm@fastdial.net
Date: Fri, 8 Sep 2000 07:49:32 CST Raw View
In article <MPG.14208f1fb6718cf298973a@news.supernews.com>,
smeyers@aristeia.com (Scott Meyers) wrote:
> // A.h
>
> class A
> {
> friend void f( A& a ) ;
> // ...
> } ;
>
> // Class1.cpp
>
> class A ;
> static void f( A& a ) ;
>
> #include "A.h"
>
> static void f( A& a )
> {
> // do whatever with a
> }
>
> // Class2.cpp
>
> // ... exactly like Class1.cpp, f does something else
>
> I'm declaring f _before_ including A.h, so f retains its static
linkage
> when A.h is parsed (11.4.3 in the draft standard). Since f is
static,
> there is no problem whatsoever with the ODR. Also, the ODR does
_not_ say
> that a friend function declaration must be resolved to the same
function
> in different translation units. Obviously this toy works fine with
any
> compiler I can get my hands on. I think it's also compliant with the
> ANSI/ISO standard. What do you think?
>
> My attention has again been drawn to the issue, so now that we have a
> standard, I'm wondering: Does Carlo's code above violate any part of
the
> standard? I'm hoping it does, but I don't know what. Who does?
At first blush, this runs afoul of the second bullet of 3.2p5
(taking class A as the "D" in the description):
in each definition of D, corresponding names, looked up
according to 3.4, shall refer... to the same entity
Because of the inclusion, class A is defined in both class1.cpp
and class2.cpp, but the name "f" in the friend declaration
refers to different entities in each file. It would thus be
a violation of the one definition rule.
However, there's a subtle interaction with a current
discussion in the Committee: the core language working group
has decided that the mechanism by which a "friend" declaration
is matched with a preceding declaration is _not_ ordinary
name lookup as defined in 3.4. It would appear that friend
declarations are thus exempt from this requirement of the
ODR.
I'm pretty sure that, after we get around to nailing down the
friend-matching mechanism, the new specification will be
added to 3.4, plugging the loophole. In the meantime, though,
I would guess there's nothing making this illegal.
--
William M. Miller, wmm@fastdial.net
Vignette Corporation (www.vignette.com)
Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: smeyers@aristeia.com (Scott Meyers)
Date: Thu, 7 Sep 2000 17:01:45 GMT Raw View
In his book, Lakos describes the problems of "long distance friendship,"
whereby a class declaring a friend can inadvertantly grant access to
multiple functions by a client who deliberately violates the ODR in such a
way that neither the compiler nor the linker can tell. I gave a talk about
this one time (over two years ago), and shortly thereafter I got this from
Carlo Pescio:
I just finished reading your slides about the long distance friendship
hole. I would say that there is a legal way to obtain a backdoor to
private date _without_ violating the One Definition Rule.
Look at this:
// A.h
class A
{
friend void f( A& a ) ;
// ...
} ;
// Class1.cpp
class A ;
static void f( A& a ) ;
#include "A.h"
static void f( A& a )
{
// do whatever with a
}
// Class2.cpp
// ... exactly like Class1.cpp, f does something else
I'm declaring f _before_ including A.h, so f retains its static linkage
when A.h is parsed (11.4.3 in the draft standard). Since f is static,
there is no problem whatsoever with the ODR. Also, the ODR does _not_ say
that a friend function declaration must be resolved to the same function
in different translation units. Obviously this toy works fine with any
compiler I can get my hands on. I think it's also compliant with the
ANSI/ISO standard. What do you think?
My attention has again been drawn to the issue, so now that we have a
standard, I'm wondering: Does Carlo's code above violate any part of the
standard? I'm hoping it does, but I don't know what. Who does?
Thanks,
Scott
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]