With GCC v3.4 CVS 20040218 it thinks that ImplBase (typedefed within its parent) is private which it is - but the class which inherits off of it via template parameter is a friend. I understand that friendship may not apply to base classes as it's not technically "in" the class yet. However my outdated version of the standard isn't clear here so I have no real way of knowing except that MSVC and GCC v3.2 compile this fine. g++ -fPIC -Wformat -Wno-reorder -Wno-non-virtual-dtor -march=i486 -mcpu=athlon-xp -fexceptions -fkeep-inline-functions -g -DFOXDLL -DUSE_POSIX -DHAVE_CONSTTEMPORARIES -D_DEBUG -DHAVE_XSHM_H -DHAVE_XCURSOR_H=1 -DHAVE_XFT_H=1 -DXTHREADS=1 -DFOX_THREAD_SAFE=1 -DHAVE_LIBDL=1 -DHAVE_CUPS_H=1 -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_SYS_WAIT_H=1 -DHAVE_DIRENT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_SYS_SELECT_H=1 -DBUILDING_TCOMMON -DFOXDLL_EXPORTS -DHAVE_JPEG_H -DHAVE_PNG_H -DHAVE_TIFF_H -DHAVE_ZLIB_H -DHAVE_OPENSSL -DHAVE_GL_H -DSUN_OGL_NO_VERTEX_MACROS -DHPOGL_SUPPRESS_FAST_API -DHAVE_GLU_H -ITnFOX/include -I/usr/kerberos/include -I/usr/X11R6/include -I/usr/include/freetype2 -Iinclude -c -o objs/Debug/TFileBySyncDev.os src/TFileBySyncDev.cxx `-mcpu=' is deprecated. Use `-mtune=' or '-march=' instead. src/TFileBySyncDev.cxx: In member function `FX::FXIPCChannel::HandledCode Tn:: TFileBySyncDevPrivate::msgReceived(FX::FXIPCMsg*)': src/TFileBySyncDev.cxx:260: warning: converting of negative value `-0x000000001' to `unsigned int' TnFOX/include/FXGenericTools.h: At global scope: TnFOX/include/FXGenericTools.h: In instantiation of `FX::Generic::FunctorHelper: :ImplMemFn<FX::Generic::Functor<FX::Generic::TL::item<FX::FXIPCChannel:: HandledCode, FX::Generic::TL::item<FX::FXIPCMsg*, FX::Generic::NullType> > >, Tn::TFileBySyncDevPrivate, FX::FXIPCChannel::HandledCode (Tn:: TFileBySyncDevPrivate::*)(FX::FXIPCMsg*)>': TnFOX/include/FXGenericTools.h:1259: instantiated from `FX::Generic:: Functor<parslist>::Functor(obj*, fn) [with obj = Tn::TFileBySyncDevPrivate, fn = FX::FXIPCChannel::HandledCode (Tn::TFileBySyncDevPrivate::*)(FX::FXIPCMsg*), parslist = FX::Generic::TL::item<FX::FXIPCChannel::HandledCode, FX::Generic::TL: :item<FX::FXIPCMsg*, FX::Generic::NullType> >]' src/TFileBySyncDev.cxx:297: instantiated from here TnFOX/include/FXGenericTools.h:1240: error: `typedef struct FX::Generic:: FunctorHelper::ImplBaseOp<FX::Generic::TL::item<FX::FXIPCChannel::HandledCode, FX::Generic::TL::item<FX::FXIPCMsg*, FX::Generic::NullType> >, 1> FX::Generic:: Functor<FX::Generic::TL::item<FX::FXIPCChannel::HandledCode, FX::Generic::TL:: item<FX::FXIPCMsg*, FX::Generic::NullType> > >::ImplBase' is private TnFOX/include/FXGenericTools.h:1195: error: within this context scons: *** [objs/Debug/TFileBySyncDev.os] Error 1 Cheers, Niall
Created attachment 5793 [details] Preprocessor output illustrating the bug (maybe)
Since you seem to know what's going on, maybe you can help us and provide a minimal snippet showing the problem?
Here's a minimal testcase showing the problem. I guess, gcc is actually right when rejecting the code (it does so since 3.3), but I'm not sure. ===================================================== template <typename T> struct A : public T::X {}; class B { template <typename> friend class A; struct X {}; }; A<B> a; =====================================================
(In reply to comment #3) > Here's a minimal testcase showing the problem. > I guess, gcc is actually right when rejecting the code > (it does so since 3.3), but I'm not sure. > > ===================================================== > template <typename T> struct A : public T::X {}; > > class B > { > template <typename> friend class A; > struct X {}; > }; > > A<B> a; > ===================================================== > This is it in one. Now seeing as you guys are the experts, does inheriting off something observe that something's friend rules? ie; does the class begin before inheriting or after? I should add I tested against v3.2 where it does work, not v3.3 which dies with certain code sequences in my code so I tend to avoid it (v3.4 has them fixed so I haven't reported these). Cheers, Niall
This is not a bug, ICC 6.0 rejects this code (but only when strict mode is turned on): pr14281.cc pr14281.cc(1): error #308: class "B::X" is inaccessible template <typename T> struct A : public T::X {}; ^ detected during instantiation of class "A<T> [with T=B]" at line 9 compilation aborted for pr14281.cc (code 2)
Well, ICC/EDG might be wrong, especially if you use such an old version. Please, let's not close bugs only because another compiler behaves differently, even if it's EDG. Anyway, this bug is indeed invalid because of [class.friend]/2 in the C++ Standard, which says: "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." So GCC is indeed correct.
Subject: Re: Regression in v3.4: friend class not working "giovannibajo at libero dot it" <gcc-bugzilla@gcc.gnu.org> writes: | Please, let's not close bugs only because another compiler behaves | differently, even if it's EDG. Amen. I wish we do not end up being a clone of EDG (I do intend to diminish their values) or do whatever EDG does. -- Gaby