[try Beta version]
Not logged in

 
bug or feature

Sep 14, 2010 at 12:15pm
I've wrote some code which failed to compile by gcc-4.4.1:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//here was mistake - struct written instead of class
class Access
{
  friend class Test;
  struct Tag 
    {};
};

template <typename AccessTag>
struct Foo
{};

class Test
  :public Foo<Access::Tag> // error: Access::Tag is private within this context
{
  Foo<Access::Tag> tag; // compiled ok
};


Can't figure out is this really error, or just a bug in compiler.
Last edited on Sep 14, 2010 at 12:48pm
Sep 14, 2010 at 12:35pm
It compiles fine with g++ 4.4.3 and 4.5.0
Sep 14, 2010 at 12:38pm
The above compiles cleanly for me under gcc 3.3.3, gcc 4.1.2 and clang.
Sep 14, 2010 at 12:47pm
Bazzy, jsmith
sorry, i've made a mistake in a sample - fixed
Sep 14, 2010 at 1:12pm
Ok, now gcc 3.3.3 and 4.1.2 both winge, but clang still compiles cleanly. I'd trust clang more than gcc,
and the code looks right to me, so I'd say it is a problem with gcc.
Sep 14, 2010 at 1:14pm
Interesting, comeau also winges for the same reason as gcc.

http://www.comeaucomputing.com/tryitout/

Sep 14, 2010 at 1:19pm
Here's the simplest version of the code I can come up with that still does not compile:

1
2
3
4
5
6
7
8
9
class Access
{
  friend struct Test;
  struct Tag {};
};

struct Test : Access::Tag
{
};


It seems that the friendship is not occurring until the open brace on struct Test.
Sep 14, 2010 at 1:28pm
@jsmith

"It seems that the friendship is not occurring until the open brace on struct Test."
Yes, and i can't still understand what the standard says about such cases.. Code looks right to me too.
Sep 16, 2010 at 1:36pm
Unlike structs all class members are private if not specified another access level. ;-)

1
2
3
4
5
class Access
{
  friend struct Test;
  struct Tag {};
};
is similar
1
2
3
4
5
6
class Access
{
  friend struct Test;
private:
  struct Tag {};
};

You must write:
1
2
3
4
5
6
class Access
{
  friend struct Test;
public:
  struct Tag {};
};
or unnatural style:
1
2
3
4
5
struct Access
{
  friend struct Test;
  struct Tag {};
};


EDIT: i mean that it is not a bug =)
Last edited on Sep 16, 2010 at 1:43pm
Sep 16, 2010 at 3:13pm
boolivar: By declaring Test to be a friend of Access (line 3 of your first code block above), Test
should have access to Access' private elements. That is what friendship does.

For comparison, take my "simplest example" code above, remove the ": Access::tag" from line 7,
and add between lines 8 and 9 a member variable of type Access::Tag. eg:

1
2
3
4
5
6
7
8
9
10
class Access
{
  friend struct Test;
  struct Tag {};
};

struct Test
{
   Access::Tag t;
};


And note that this compiles cleanly.
Sep 17, 2010 at 6:40am
This compiles cleanly:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Access
{
  friend class Test;

private:
  class Tag {};
};

class Test
{
public:
  class T : Access::Tag {};
};


That is what friendship does.
Sep 17, 2010 at 6:59am
@boolivar
look at comment at string 16 in original example - the question was not about friendship and access inside the class braces.

However, i found the answer in 11.4.2 of the standard, quote:

Also, because the base-clause of the friend class is not part of its member declarations, the base-clause of the friend class cannot access the names of the private and protected members from the class granting friendship.

end qoute

So this is not a bug, alas.
Last edited on Sep 17, 2010 at 7:02am
Sep 17, 2010 at 7:13am
But the good news that in C++0x (according to http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3126.pdf) the corresponding rule is

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.

end quote
Sep 17, 2010 at 2:11pm
Thank you for the enlightenment.

I guess every compiler we tried was right then, since there is no wrong answer. It's just
a matter of what version of the standard your compiler claims to support :)

Topic archived. No new replies allowed.