Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this a bug in g++ or clang++

Tags:

c++

g++

clang++

The following code:

class A
{
  friend class B;
  int m;
};

class B
{
  friend void f(A* p) { p->m = 32; }
};

Compiles in clang version 9.0.0-2, but not in g++ version 9.2.1

friend-test.cpp: In function ‘void f(A*)’:
friend-test.cpp:10:28: error: ‘int A::m’ is private within this context
   10 |   friend void f(A* p) { p->m = 32; }
      |                            ^
friend-test.cpp:5:7: note: declared private here
    5 |   int m;
      |       ^

Which compiler is right?

like image 389
Grzegorz Jablonski Avatar asked Jan 01 '23 08:01

Grzegorz Jablonski


2 Answers

GCC is in the right. Clang appears to have a bug.

[class.friend]

10 Friendship is neither inherited nor transitive. [ Example:

class A {
  friend class B;
  int a;
};

class B {
  friend class C;
};

class C  {
  void f(A* p) {
    p->a++;         // error: C is not a friend of A despite being a friend of a friend
  }
};

class D : public B  {
  void f(A* p) {
    p->a++;         // error: D is not a friend of A despite being derived from a friend
  }
};

 — end example ]

The fact f is a friend of B and B is in turn a friend of A doesn't mean f is allowed to access A's private parts.

like image 187
StoryTeller - Unslander Monica Avatar answered Jan 02 '23 21:01

StoryTeller - Unslander Monica


According to the C++ 17 Standard (14.3 Friends)

10 Friendship is neither inherited nor transitive

Thus the compiler clang has a bug.

It is interesting to note that if to define the function outside the class B like

class B
{
    public:
    friend void f(A* p);
};

void f(A* p) { p->m = 32; }

then in this case the compiler clang HEAD 10.0.0 issues an error

rog.cc:18:19: error: 'm' is a private member of 'A'
void f(A* p) { p->m = 32; }
                  ^
prog.cc:9:7: note: implicitly declared private here
  int m;
      ^
1 error generated.

So without any doubts the compiler has a bug.

like image 40
Vlad from Moscow Avatar answered Jan 02 '23 23:01

Vlad from Moscow