From: Raoul G. <Rao...@ya...> - 2002-05-27 10:41:20
|
From: "Danny Smith" <dan...@ya...> To: "Raoul Gough" <Rao...@ya...>; <min...@li...> Sent: Sunday, May 26, 2002 10:08 PM > --- Raoul Gough <Rao...@ya...> wrote: > > > > struct __attribute__((dllexport)) foo > > { > > void foofunction () { } > > }; > > [snip] > > Actually I like the current behaviour. If the inline function is not used, it > is discarded. The same behaviour is seen when building a static lib, so it is > not really a dllexport issue. The difference with a static library is that the inline member actually does get inlined in the client code. However, if the class has the dll_im_port attribute then the client class does not inline the member. IMHO, this is also the correct behaviour, because otherwise you couldn't upgrade the dll without recompiling - some stuff would get upgraded, but all the inline things would have been hard-wired into the client. In any case, the real problem with the current gcc behaviour is that it is inconsistent - inline member functions with dllexport can get discarded, whereas references to dllimported inline member functions are *not* inlined. This is what originally caused the problem for me (both with the Boost Python library and, dare I mention it, STLport). The generated dll's don't contain the inline member functions, whereas the client code has unresolved externals for them. The reason for this discrepancy is, AFAICT, that the backend code that understands dllexport doesn't get reached, because the frontend decides to set comdat_flag and discard the function before code generation takes place. On the other hand, a reference to a dllimport function that actually does get code-generated will see the dllimport flag and prevent inlining. > > To force a global symbol of an inline function in the object file, either use > it, like so: > > struct __declspec(dllexport) foo > { > void foofunction (){ } > }; > void(foo::*funptr )(void) = &foo::foofunction; > > > Or, better IMO, tell GCC to not discard: > > struct __declspec(dllexport) foo > { > void __attribute__((used)) foofunction (){ } > }; That's a new one on me. I guess that would be the preferred work-around for the user. I first tried using the -fkeep-inline-functions or -fno-default-inline flag, but these crash the compiler in the dllimport case (toplev.c:3478). This means that if any module both exports and imports inline members these flags won't help. Not that fixing the crash wouldn't be a good thing in itself, but I think this is a separate issue. So I guess the real question is what the semantics of the dllexport attribute on a class really are. Maybe it should just match whatever MS VC++ does, in order to provide compatability (isn't this the whole reason for declspec in the first place?) There is certainly some code out there that relies, perhaps unwittingly, on the 2.95.3 behaviour, which has now changed. Regards, Raoul Gough. _________________________________________________________ Do You Yahoo!? Get your free @yahoo.com address at http://mail.yahoo.com |