By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,079 Members | 940 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,079 IT Pros & Developers. It's quick & easy.

friend ceclaration/definition - is this valid?

P: n/a
rn
the code below compiles OK with gcc 4.0 but not with gcc.4.2 and visual
studio 2005 (ver 8 ).

to me it seems it should not compile.

-----

class test1
{
public:

friend test1* newtest1(int x)
{
test1* anobj = new test1();
anobj->finishinit(x);
return anobj;
}

virtual ~test1()
{
}

private:

int avalue;

test1()
{
avalue = 0;
}

void finishinit(int x)
{
avalue = x;
}
};

int main(int argc, char *argv[])
{
test1* tobj = newtest1(5);
delete tobj;

}

Aug 9 '08 #1
Share this Question
Share on Google+
4 Replies


P: n/a

Hello,

Why should it not compile? I happened to notice that same question was
answered and reference to standards given in:
http://lists.apple.com/archives/coco.../msg00669.html

Regards.
Aug 9 '08 #2

P: n/a
My understanding is that the f in

struct X { friend X* f(); };

cannot be called until it is declared, neither by members of X or by
anything else in the same namespace or another namespace, as per section
7.3.1.2 paragraph 3 of the standard:

"Every name first declared in a namespace is a member of that namespace.
If a friend declaration in a non-local class first declares a class or
function the friend class or function is a member of the innermost
enclosing namespace. The name of the friend is not found by simple name
lookup until a matching declaration is provided in that namespace scope
(either before or after the class declaration granting friendship).
[...]"

The fix would be to declare f first:

struct X;
X* f();
struct X { friend X* f(); };
Aug 10 '08 #3

P: n/a
On Aug 9, 9:51 pm, "rn" <nowaynos...@nowaynospam.comwrote:
the code below compiles OK with gcc 4.0 but not with gcc.4.2
and visual studio 2005 (ver 8 ).
to me it seems it should not compile.
So what are you complaining about? g++ 4.0 had a bug, which has
been corrected, and everything is fine.

More likely, however, you meant that it should compile:-).
-----
class test1
{
public:
friend test1* newtest1(int x)
Note that this declaration doesn't make the name of the function
visible anywhere but in test1. In pre-standard C++, the name of
a friend function was "injected" into the surrounding namespace
scope (actually into file scope, because in pre-standard C++,
there weren't namespaces). The standard changed this, for a
reason I forget (it's been explained to me several times, but
I've forgotten it as many times); according to the standard,
this name can only be found 1) in newtest1, or 2) using ADL
(except that since it only takes an int as an argument, ADL
can't ever find it, since there are no associated namespaces).

You'll need some declaration in global namespace if you want to
use the function outside of test1.
{
test1* anobj = new test1();
anobj->finishinit(x);
return anobj;
}
virtual ~test1()
{
}
private:
int avalue;
test1()
{
avalue = 0;
}
void finishinit(int x)
{
avalue = x;
}
};
int main(int argc, char *argv[])
{
test1* tobj = newtest1(5);
Here, you're not in the class test1, and there's no declaration
of newtest1 that is visible. So the code shouldn't compile.
delete tobj;
}
--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Aug 10 '08 #4

P: n/a
rn

"James Kanze" <ja*********@gmail.comskrev i meddelandet
news:99**********************************@b1g2000h sg.googlegroups.com...
On Aug 9, 9:51 pm, "rn" <nowaynos...@nowaynospam.comwrote:
the code below compiles OK with gcc 4.0 but not with gcc.4.2
and visual studio 2005 (ver 8 ).
to me it seems it should not compile.
>So what are you complaining about?
I'm not complaining, I was asking a question
g++ 4.0 had a bug, which has
been corrected, and everything is fine.
exactly and that's what I'm trying to confirm
>More likely, however, you meant that it should compile:-).
No, I meant that it should not compile which it does on gcc 4.0
but not on gcc 4.2 and Visual Studio

So the code is wrong which I wanted to confirm


-----
class test1
{
public:
friend test1* newtest1(int x)
Note that this declaration doesn't make the name of the function
visible anywhere but in test1. In pre-standard C++, the name of
a friend function was "injected" into the surrounding namespace
scope (actually into file scope, because in pre-standard C++,
there weren't namespaces). The standard changed this, for a
reason I forget (it's been explained to me several times, but
I've forgotten it as many times); according to the standard,
this name can only be found 1) in newtest1, or 2) using ADL
(except that since it only takes an int as an argument, ADL
can't ever find it, since there are no associated namespaces).

You'll need some declaration in global namespace if you want to
use the function outside of test1.
{
test1* anobj = new test1();
anobj->finishinit(x);
return anobj;
}
virtual ~test1()
{
}
private:
int avalue;
test1()
{
avalue = 0;
}
void finishinit(int x)
{
avalue = x;
}
};
int main(int argc, char *argv[])
{
test1* tobj = newtest1(5);
Here, you're not in the class test1, and there's no declaration
of newtest1 that is visible. So the code shouldn't compile.
delete tobj;
}
--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Aug 10 '08 #5

This discussion thread is closed

Replies have been disabled for this discussion.