friend class can't access private member

2,146 views
Skip to first unread message

Munjal Doshi

unread,
May 16, 2012, 4:19:25 PM5/16/12
to Chromium-dev
Need some help with C++ expertise.

This patch fails to compile on linux and linux_chromeos (though it passes on linux_clang).

The relevant files are web_auth_flow.h and web_auth_flow_unittest.cc

WebAuthFlow declares WebAuthFlowTest as a friend.
WebAuthFlowTest has protected wrappers for some private methods in WebAuthFlow, namely CallOnClose and CallIsValidRedirectUrl.
The only notable thing here is that WebAuthFlowTest uses a pointer to MockWebAuthFlow that derives from WebAuthFlow when it calls proviate methods. But I tried to circumvent that by using a WebAuthFlow* instead of MockWebAuthFlow* with no luck.

All of it compiles on mac and windows but on linux it fails with the error:
./chrome/browser/extensions/api/identity/web_auth_flow.h: In member function 'void WebAuthFlowTest::CallOnClose()':
./chrome/browser/extensions/api/identity/web_auth_flow.h:82: error: 'virtual void extensions::WebAuthFlow::OnClose()' is private
chrome/browser/extensions/api/identity/web_auth_flow_unittest.cc:117: error: within this context
./chrome/browser/extensions/api/identity/web_auth_flow.h: In member function 'bool WebAuthFlowTest::CallIsValidRedirectUrl(const GURL&)':
./chrome/browser/extensions/api/identity/web_auth_flow.h:92: error: 'bool extensions::WebAuthFlow::IsValidRedirectUrl(const GURL&) const' is private
chrome/browser/extensions/api/identity/web_auth_flow_unittest.cc:121: error: within this context
If anyone has an idea, it would be greatly helpful to know.

-Munjal

Ilya Sherman

unread,
May 16, 2012, 4:27:24 PM5/16/12
to mun...@chromium.org, Chromium-dev
I believe the issue is that WebAuthFlow is defined within the extensions:: namespace, whereas WebAuthFlowTest is not.  I think you can either wrap the test with the same namespace, or friend class ::WebAuthFlowTest.
 

-Munjal

--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev

Lei Zhang

unread,
May 16, 2012, 4:41:42 PM5/16/12
to mun...@chromium.org, ishe...@chromium.org, Chromium-dev
This has bitten me a few times. Take a look at the second code snippet
in base/gtest_prod_util.h.

Simon Hong

unread,
May 16, 2012, 5:10:51 PM5/16/12
to mun...@chromium.org, the...@chromium.org, ishe...@chromium.org, Chromium-dev
friend class WebAuthFlowTest;

I think "friend class WebAuthFlowTest" in extensions namespace is implicitly same as "friend class extensions::WebAuthFlowTest" not  "friend class ::WebAuthFlowTest".
======================================
Simon Hong
"Secret of success is consistency to purpose"

Munjal Doshi

unread,
May 16, 2012, 5:15:50 PM5/16/12
to Simon Hong, the...@chromium.org, ishe...@chromium.org, Chromium-dev
Thanks a ton all. That was it. It is so subtle. Especially since it worked on other platforms (due to forward declaration of WebAuthFlowTest outside extensions namespace) and not on linux, it was hard to figure this out (already spent a day trying out various other techniques).

There is one question though: I can fix the "friend class ::WebAuthFlowTest". But if I used FRIEND_TEST_ALL_PREFIXES macro, how would I do it? Oh I suppose I can pass ::WebAuthFlowTest as first arg to the macro.

-Munjal

Fred Akalin

unread,
May 16, 2012, 5:20:21 PM5/16/12
to mun...@chromium.org, Simon Hong, the...@chromium.org, ishe...@chromium.org, Chromium-dev
It's worth mentioning that it might be easier to just add ...ForTest() methods to the appropriate classes instead of trying to wrangle with friend declarations, protected wrappers around private members, etc.

Munjal Doshi

unread,
May 16, 2012, 5:23:33 PM5/16/12
to Fred Akalin, Simon Hong, the...@chromium.org, ishe...@chromium.org, Chromium-dev
Protected wrappers for private methods was a workaround I was trying.

The real thing I started with (like in other tests) is just declaring test classes as friends:
friend class WebAuthFlowTest;
FRIEND_TEST_ALL_PREFIXES(WebAuthFlowTest, <some test>);

I like to use that versus extra methods so that the public interface of the class remains minimal, and encapsulation is broken only in testing.

-Munjal

Alexandre Elias

unread,
May 18, 2012, 1:36:22 AM5/18/12
to mun...@chromium.org, Chromium-dev
On Wed, May 16, 2012 at 2:15 PM, Munjal Doshi <mun...@chromium.org> wrote:
> Thanks a ton all. That was it. It is so subtle. Especially since it worked
> on other platforms (due to forward declaration of WebAuthFlowTest outside
> extensions namespace) and not on linux, it was hard to figure this out
> (already spent a day trying out various other techniques).

Yeah, forward declarations and namespaces don't mix well. A related
problem I've run into is that if a class is ever forward declared in
the wrong namespace -- particularly if it's in a widely used header --
it creates a cascade of potential compile errors in other files, and
it can be hard to track down the root cause of the issue.
Reply all
Reply to author
Forward
0 new messages