简体   繁体   中英

Is this a bug in g++ or 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?

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM