C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Scope of friends defined in classes

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards
View previous topic :: View next topic  
Author Message
Scott Meyers
Guest





PostPosted: Fri Dec 10, 2004 10:56 pm    Post subject: Scope of friends defined in classes Reply with quote



It would not surprise me if this has been hashed over before, but I was
unable to unearth anything via Google. Feel free to respond with a URL if
this is an old topic.

11.4/5 says:

A function can be defined in a friend declaration of a class if and only if
the class is a non-local class (9.Cool, the function name is unqualified, and
the function has namespace scope. [Example:

class M {
friend void f() { } // definition of global f, a friend of M,
// not the definition of a member function
};

end example] Such a function is implicitly inline. A friend function
defined in a class is in the (lexical) scope of the class in which it is
defined. A friend function defined outside the class is not (3.4.1).

This suggests to me that this should not compile:

class M { ... }; // as above

int main()
{
f(); // should not compile; though f is global, it's
} // in the lexical scope of M

Two of my compilers agree with me. However, 11.4/5 also suggests to me
that the following SHOULD compile:

class M {
friend void f(){} // as before
static void g()
{ f(); } // should compile: call to (global) f from within
}; // the lexical scope of M

Both compilers disagree with me.

Who's right, and why?

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://www.jamesd.demon.co.uk/csc/faq.html ]

Back to top
Victor Bazarov
Guest





PostPosted: Sat Dec 11, 2004 9:47 am    Post subject: Re: Scope of friends defined in classes Reply with quote



"Scott Meyers" <Usenet (AT) aristeia (DOT) com> wrote...
Quote:
It would not surprise me if this has been hashed over before, but I was
unable to unearth anything via Google. Feel free to respond with a URL if
this is an old topic.

I've found quite a few discussions on friends defined in a class definition,
not sure which ones you'd like to see.

Try http://tinyurl.com/62lna

Also, see 7.3.1.2/3 Since a definition is also a declaration, that applies,
AFAICT. To be used outside the class the function has to be declared
outside
that class.

Quote:
11.4/5 says:

A function can be defined in a friend declaration of a class if and only
if
the class is a non-local class (9.Cool, the function name is unqualified,
and
the function has namespace scope. [Example:

class M {
friend void f() { } // definition of global f, a friend of M,
// not the definition of a member function
};

end example] Such a function is implicitly inline. A friend function
defined in a class is in the (lexical) scope of the class in which it is
defined. A friend function defined outside the class is not (3.4.1).

This suggests to me that this should not compile:

class M { ... }; // as above

int main()
{
f(); // should not compile; though f is global, it's
} // in the lexical scope of M

Two of my compilers agree with me. However, 11.4/5 also suggests to me
that the following SHOULD compile:

class M {
friend void f(){} // as before
static void g()
{ f(); } // should compile: call to (global) f from within
}; // the lexical scope of M

Both compilers disagree with me.

Who's right, and why?

I think you're right.

V

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Andrew Koenig
Guest





PostPosted: Sat Dec 11, 2004 6:07 pm    Post subject: Re: Scope of friends defined in classes Reply with quote



"Scott Meyers" <Usenet (AT) aristeia (DOT) com> wrote


Quote:
It would not surprise me if this has been hashed over before, but I was
unable to unearth anything via Google. Feel free to respond with a URL if
this is an old topic.

11.4/5 says:

A function can be defined in a friend declaration of a class if and only
if
the class is a non-local class (9.Cool, the function name is unqualified,
and
the function has namespace scope. [Example:

class M {
friend void f() { } // definition of global f, a friend of M,
// not the definition of a member function
};

end example] Such a function is implicitly inline. A friend function
defined in a class is in the (lexical) scope of the class in which it is
defined. A friend function defined outside the class is not (3.4.1).

What that means is that the body of the function can refer to other members
of M, even though f itself is injected into the scope surrounding M.

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Scott Meyers
Guest





PostPosted: Sun Dec 12, 2004 7:04 pm    Post subject: Re: Scope of friends defined in classes Reply with quote

Relatedly, I'm trying to figure out what it means for a function to be
global, but in the lexical scope of a class. Consider the example again
from 11.4/5:

class M {
friend void f() { } // definition of global f, a friend of M,
// not the definition of a member function
};

f is global, so that suggests that trying to define another f at global
scope should be invalid. But the f above is in the lexical scope of M,
and that suggests that defining another f in the global lexical scope
might be okay. But maybe that would be an ODR violation that does not
require a diagnostic...

So should this compile?

class M {
friend void f() { } // f is globol, but in M's lexical scope
};

void f() { int x; } // f is global, but in the global lexical scope

VC7.1, g++ 3.2, and Comeau 4.3.3 all say no, complaining that f is being
redefined. Are they correct?

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://www.jamesd.demon.co.uk/csc/faq.html ]

Back to top
Victor Bazarov
Guest





PostPosted: Mon Dec 13, 2004 8:37 am    Post subject: Re: Scope of friends defined in classes Reply with quote

"Andrew Koenig" <ark (AT) acm (DOT) org> wrote...
Quote:
"Scott Meyers" <Usenet (AT) aristeia (DOT) com> wrote in message
news:MPG.1c23c6bb17bfdbb59897a9 (AT) news (DOT) hevanet.com...

It would not surprise me if this has been hashed over before, but I was
unable to unearth anything via Google. Feel free to respond with a URL
if
this is an old topic.

11.4/5 says:

A function can be defined in a friend declaration of a class if and only
if
the class is a non-local class (9.Cool, the function name is unqualified,
and
the function has namespace scope. [Example:

class M {
friend void f() { } // definition of global f, a friend of M,
// not the definition of a member function
};

end example] Such a function is implicitly inline. A friend function
defined in a class is in the (lexical) scope of the class in which it is
defined. A friend function defined outside the class is not (3.4.1).

What that means is that the body of the function can refer to other
members of M, even though f itself is injected into the scope surrounding
M.

Let me get this straight. It would seem that only static members and types
declared in M would actually be the members that function can refer to, yes?
And "car refer" probably means that it doesn't need to qualify those names,
is that correct? IOW,

class M {
typedef int blah;
class MM {};
static double d;
static void foo();

friend void f() {
blah b; // uses M::blah without 'M::'
MM mm; // *******
d = 3.14;
foo(); // calls M::foo ********
}
};

One thing is a bit unclear. What if there is '::foo'? Or '::MM'? Which
ones
will be used on the lines marked with asterisks, 'M::' or '::'?

Thank you.

Victor

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
David Abrahams
Guest





PostPosted: Mon Dec 13, 2004 8:38 am    Post subject: Re: Scope of friends defined in classes Reply with quote

Scott Meyers wrote:
Quote:
Relatedly, I'm trying to figure out what it means for a function to be
global, but in the lexical scope of a class. Consider the example again
from 11.4/5:

class M {
friend void f() { } // definition of global f, a friend of M,
// not the definition of a member function
};

f is global, so that suggests that trying to define another f at global
scope

mith the same arguments.

Quote:
should be invalid. But the f above is in the lexical scope of M,
and that suggests that defining another f in the global lexical scope
might be okay.

It's not.

Quote:
But maybe that would be an ODR violation that does not
require a diagnostic...

So should this compile?

class M {
friend void f() { } // f is globol, but in M's lexical scope
};

void f() { int x; } // f is global, but in the global lexical scope

VC7.1, g++ 3.2, and Comeau 4.3.3 all say no, complaining that f is being
redefined. Are they correct?

Yes they are.

HTH,
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Roger Orr
Guest





PostPosted: Wed Dec 15, 2004 12:53 am    Post subject: Re: Scope of friends defined in classes Reply with quote

""Victor Bazarov"" <v.Abazarov (AT) comAcast (DOT) net> wrote

[snip]
Quote:
What that means is that the body of the function can refer to other
members of M, even though f itself is injected into the scope
surrounding
M.

Let me get this straight. It would seem that only static members and
types
declared in M would actually be the members that function can refer to,
yes?
And "car refer" probably means that it doesn't need to qualify those
names,
is that correct? IOW,

class M {
typedef int blah;
class MM {};
static double d;
static void foo();

friend void f() {
blah b; // uses M::blah without 'M::'
MM mm; // *******
d = 3.14;
foo(); // calls M::foo ********
}
};

One thing is a bit unclear. What if there is '::foo'? Or '::MM'? Which
ones
will be used on the lines marked with asterisks, 'M::' or '::'?

Why is it unclear - surely the usual scope rules apply so MM means M::MM ?

Roger Orr
--
MVP in C++ at www.brainbench.com


---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Victor Bazarov
Guest





PostPosted: Wed Dec 15, 2004 5:39 am    Post subject: Re: Scope of friends defined in classes Reply with quote

"Roger Orr" <rogero (AT) howzatt (DOT) demon.co.uk> wrote...
Quote:
""Victor Bazarov"" <v.Abazarov (AT) comAcast (DOT) net> wrote in message
news:qjIud.245775$R05.129920 (AT) attbi_s53 (DOT) ..
[snip]
What that means is that the body of the function can refer to other
members of M, even though f itself is injected into the scope
surrounding
M.

Let me get this straight. It would seem that only static members and
types
declared in M would actually be the members that function can refer to,
yes?
And "car refer" probably means that it doesn't need to qualify those
names,
is that correct? IOW,

class M {
typedef int blah;
class MM {};
static double d;
static void foo();

friend void f() {
blah b; // uses M::blah without 'M::'
MM mm; // *******
d = 3.14;
foo(); // calls M::foo ********
}
};

One thing is a bit unclear. What if there is '::foo'? Or '::MM'? Which
ones
will be used on the lines marked with asterisks, 'M::' or '::'?

Why is it unclear - surely the usual scope rules apply so MM means M::MM ?

OK, so, 'being in lexical scope' defines how names used inside the function
are resolved, first the innermost scope, then outer, etc., right? Also, the
function arguments are in the scope too, right? So, this:

class M {
typedef int blah;
friend void foo(blah b) { b + 42; }
};

void foo(int);

int main() {
foo(33);
}

is a valid program, correct? OK, Comeau compiles fine. Now, this one:

class M {
typedef int blah;
friend void foo(blah b) { b + 42; }
public:
static void bar() { foo(33); } // line 5
};

int main() {
M::bar();
}

Causes the error

"ComeauTest.c", line 5: error: identifier "foo" is undefined
static void bar() { foo(33); } // line 5
^

V

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Roger Orr
Guest





PostPosted: Thu Dec 16, 2004 4:57 am    Post subject: Re: Scope of friends defined in classes Reply with quote

""Victor Bazarov"" <v.Abazarov (AT) comAcast (DOT) net> wrote

Quote:
"Roger Orr" <rogero (AT) howzatt (DOT) demon.co.uk> wrote...
[snip]
OK, so, 'being in lexical scope' defines how names used inside the
function
are resolved, first the innermost scope, then outer, etc., right? Also,
the
function arguments are in the scope too, right? So, this:

class M {
typedef int blah;
friend void foo(blah b) { b + 42; }
};

void foo(int);

int main() {
foo(33);
}

is a valid program, correct? OK, Comeau compiles fine. Now, this one:

class M {
typedef int blah;
friend void foo(blah b) { b + 42; }
public:
static void bar() { foo(33); } // line 5
};

int main() {
M::bar();
}

Causes the error

"ComeauTest.c", line 5: error: identifier "foo" is undefined
static void bar() { foo(33); } // line 5
^

I think this is a bug. But I always worry when I disagree with Comeau...

15.4p7: A name nominated by a friend declaration shall be accessible in the
scope of the class containing the friend declaration.

Roger Orr
--
MVP in C++ at www.brainbench.com


---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
John Potter
Guest





PostPosted: Thu Dec 16, 2004 8:50 pm    Post subject: Re: Scope of friends defined in classes Reply with quote

On Thu, 16 Dec 2004 04:57:32 GMT, [email]rogero (AT) howzatt (DOT) demon.co.uk[/email] ("Roger
Orr") wrote:

Quote:
""Victor Bazarov"" <v.Abazarov (AT) comAcast (DOT) net> wrote in message
news:ngNvd.187201$5K2.43852 (AT) attbi_s03 (DOT) ..

class M {
typedef int blah;
friend void foo(blah b) { b + 42; }
public:
static void bar() { foo(33); } // line 5
};
int main() {
M::bar();
}

Causes the error

"ComeauTest.c", line 5: error: identifier "foo" is undefined
static void bar() { foo(33); } // line 5
^

I think this is a bug. But I always worry when I disagree with Comeau...

15.4p7: A name nominated by a friend declaration shall be accessible in the
scope of the class containing the friend declaration.

I think you may be missing the meaning of "shall". It says that the
name nominated "shall" be accessible not that it "will become". It
prevents nominating a private member of another class as a friend
because that would not be accessible.

It is also not found by ADL because 33 is just an int. Add a
declaration of foo before the class and it will compile.

John

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Victor Bazarov
Guest





PostPosted: Thu Dec 16, 2004 10:50 pm    Post subject: Re: Scope of friends defined in classes Reply with quote

John Potter wrote:
Quote:
On Thu, 16 Dec 2004 04:57:32 GMT, [email]rogero (AT) howzatt (DOT) demon.co.uk[/email] ("Roger
Orr") wrote:


""Victor Bazarov"" <v.Abazarov (AT) comAcast (DOT) net> wrote in message
news:ngNvd.187201$5K2.43852 (AT) attbi_s03 (DOT) ..


class M {
typedef int blah;
friend void foo(blah b) { b + 42; }
public:
static void bar() { foo(33); } // line 5
};
int main() {
M::bar();
}


Causes the error


"ComeauTest.c", line 5: error: identifier "foo" is undefined
static void bar() { foo(33); } // line 5
^


I think this is a bug. But I always worry when I disagree with Comeau...


15.4p7: A name nominated by a friend declaration shall be accessible in the

11.4p7 (got me a minute to locate it :-)

Quote:
scope of the class containing the friend declaration.


I think you may be missing the meaning of "shall". It says that the
name nominated "shall" be accessible not that it "will become". It
prevents nominating a private member of another class as a friend
because that would not be accessible.

It is also not found by ADL because 33 is just an int. Add a
declaration of foo before the class and it will compile.

That sounds reasonable, thank you, John. But now I have more questions.

What would be the point of defining a friend inside the class definition
if you cannot call it without having at least declared it outside _before_
the class definition? And how to fit this {"shall" versus "will become"}
explanation with a simple notion that every definition of a function is
also a declaration (3.1/2)? Or is it enough that 11.4 basically says that
a friend definition inside is _not_ a declaration (although without using
these particular words)?

I started reading 11.4/5 again and noticed these words: "and the function
has namespace scope". What does that mean? If the name is unqualified,
what other scope is there? Or does it mean that the function name has to
be already known by the time the compiler encounters the definition [of
the friend function inside the class]?

Thanks again.

Victor

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
rogero@howzatt.demon.co.u
Guest





PostPosted: Sun Dec 19, 2004 1:58 am    Post subject: Re: Scope of friends defined in classes Reply with quote

Victor Bazarov wrote:
Quote:
John Potter wrote:
"Roger Orr") wrote:
""Victor Bazarov"" <v.Abazarov (AT) comAcast (DOT) net> wrote

class M {
typedef int blah;
friend void foo(blah b) { b + 42; }
public:
static void bar() { foo(33); } // line 5
};
int main() {
M::bar();
}

"ComeauTest.c", line 5: error: identifier "foo" is undefined
static void bar() { foo(33); } // line 5
^

I think this is a bug. But I always worry when I disagree with
Comeau...


15.4p7: A name nominated by a friend declaration shall be
accessible in the

11.4p7 (got me a minute to locate it Smile

Sorry :-)

Quote:
scope of the class containing the friend declaration.

I think you may be missing the meaning of "shall". It says that
the
name nominated "shall" be accessible not that it "will become". It
prevents nominating a private member of another class as a friend
because that would not be accessible.

Looks like I was getting too tired to concentrate - thanks for your
input, John!

Quote:
What would be the point of defining a friend inside the class
definition
if you cannot call it without having at least declared it outside
_before_
the class definition?

There is a point -- if you call the function using ADL. I suspect the
principal usage is for friend operators.

class X
{
friend X operator+( int, X ) { /* ... */ }
};

then
X x1;
X x2;

x1 = 1 + x2;

Quote:
And how to fit this {"shall" versus "will become"}
explanation with a simple notion that every definition of a function
is
also a declaration (3.1/2)? Or is it enough that 11.4 basically says
that
a friend definition inside is _not_ a declaration (although without
using
these particular words)?

I still think (despite having misread the paragraph) that the
definition
should be a declaration - at least as far as 'M' is concerned.
If this is not the case then I think it must be made clearer in the
standard.

Quote:
I started reading 11.4/5 again and noticed these words: "and the
function
has namespace scope". What does that mean? If the name is
unqualified,
what other scope is there? Or does it mean that the function name
has to
be already known by the time the compiler encounters the definition
[of
the friend function inside the class]?

It may mean that the function cannot be a member function of an outer
class:

class X
{
void f();
class Y
{
friend void f() { /* illegal? */ }
};
};

Returning to the original code,
should it compile if the static member function became:

static void bar() {
void foo( blah );
foo(33); }

(Comeau at any rate likes it)
HTH
Roger Orr
--
MVP in C++ at www.brainbench.com

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
John Potter
Guest





PostPosted: Tue Dec 21, 2004 11:04 pm    Post subject: Re: Scope of friends defined in classes Reply with quote

On Sat, 18 Dec 2004 19:58:33 CST, [email]rogero (AT) howzatt (DOT) demon.co.uk[/email] wrote:

Quote:
Victor Bazarov wrote:
John Potter wrote:
"Roger Orr") wrote:
""Victor Bazarov"" <v.Abazarov (AT) comAcast (DOT) net> wrote

class M {
typedef int blah;
friend void foo(blah b) { b + 42; }
public:
static void bar() { foo(33); } // line 5
};
int main() {
M::bar();
}

[snip]

Quote:
And how to fit this {"shall" versus "will become"}
explanation with a simple notion that every definition of a function
is
also a declaration (3.1/2)? Or is it enough that 11.4 basically says
that
a friend definition inside is _not_ a declaration (although without
using
these particular words)?

I still think (despite having misread the paragraph) that the
definition
should be a declaration - at least as far as 'M' is concerned.
If this is not the case then I think it must be made clearer in the
standard.

The rules were changed along the road to standardization. The
definition is a declaration; however, the name is not injected
into the enclosing namespace as it once was. It seemed inappropriate
for the class to inject a name outward. If there is a declaration
in the enclosing namespace, it is a declaration of this defined
function and makes the name visible in that namespace.

Quote:
I started reading 11.4/5 again and noticed these words: "and the
function
has namespace scope". What does that mean? If the name is
unqualified,
what other scope is there? Or does it mean that the function name
has to
be already known by the time the compiler encounters the definition
[of
the friend function inside the class]?

It may mean that the function cannot be a member function of an outer
class:

Yes.

Quote:
class X
{
void f();
class Y
{
friend void f() { /* illegal? */ }
};
};

It appears from compilers that it is not illegal. I guess that we must
read the above to mean that the function has namespace scope regardless
of the outer class function of the same name.

Quote:
Returning to the original code,
should it compile if the static member function became:

static void bar() {
void foo( blah );
foo(33); }

(Comeau at any rate likes it)

Yes. That declaration of foo is like any other declaration of an
enclosing namespace function. It makes no difference whether it
is in the member function or the namespace.

John

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.