Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT sourceware DOT cygnus DOT com Delivered-To: mailing list cygwin AT sourceware DOT cygnus DOT com From: gschmidt AT pinball-wizard DOT mit DOT edu Message-Id: <199911210828.DAA04748@pinball-wizard.mit.edu> To: cygwin AT sourceware DOT cygnus DOT com Cc: Mumit Khan , gcc AT gcc DOT gnu DOT org Subject: Workaround for virtual function/dllimport bug, also patch guidance request In-reply-to: Your message of "Wed, 17 Nov 1999 12:06:38 CST." <199911171806 DOT MAA07458 AT pluto DOT xraylith DOT wisc DOT edu> Date: Sun, 21 Nov 1999 03:28:21 EST Mumit Khan writes: > There are a few nasty bugs when you have virtual functions and also > inline functions in DLL imported classes. It's going to take quite > a few tweaks in the C++ front end to fix these, and unfortunately > I don't have the time right now. Hopefully someone else will jump > in fix these ... the vtable issue is particular harder to fix since > the GNU C++ vtables use offsets, which don't work for dllimported > functions. I finally gritted my teeth and dove into the source last night. My understanding of the problem is that dllimported functions currently can't appear in vtables, so when you derive a child class from a parent class exported from a DLL and don't override all of the virtual members, you get the aforementioned error. Normally when you take the address of a dllimported function in global scope, ie void func(void) __declspec(dllimport); void (*some_pointer)(void) = func; GCC works around the problem of func not having an address knowable at compiletime by generating an initialization function that's called automatically at startup that sets func to the correct value. But vtables are handled separately and GCC aborts instead of knowing to add the vtable to the runtime-init list. As far as I can tell the offset data, whether in the vtable or a thunk function, isn't part of the problem -- it can be computed at compile-time from the header files, right? A workaround exists. Keep in mind that if a function isn't declared dllimport but is in fact imported from a DLL, the springboard function in the import library gets used (at a slight performance penalty.) Since you *can* take the address of the springboard function at compile time, it can go in the vtable, so if you simply *don't declare virtual functions as dllimport* but just make sure they're exported correctly when the import library is made, everything will be fine (except for the small performance hit.) However, you still must declare any static class data as dllimport. So instead of tagging the whole class __declspec(dllimport), you have to individually tag just the static data members, and optionally non-virtual functions for performace. I've tested this in a toy case and it seems to work as reasoned. Since I don't want to go through the whole library retagging all of the classes, and since I want to keep MSVC compatibility, and since this case should really be handled correctly, I've been thinking about the best way to patch this. I know very little about GCC so any suggestions are appreciated. Should I: -- add code to finish_file or thereabouts to catch the case where a vtable would contain addresses not known at compiletime and tack stuff on to the static storage duration function (the ___static_initialization_ and_destruction thingy) to init the vtable at runtime? this is the "right way" in the sense that the springboard function isn't used, so it's most efficient at the expense of a few extra bytes of init function.. -- hack the dllimport attribute so that when it's applied to a class, it filters down only to members that are static data or non-virtual functions, and is automatically turned off for virtual functions (even if you try to do it manually, I guess)? this has the advantage of not touching the front end, just config/i386/winnt.c (or that's my initial impression).. -- something else? thanks, Geoff Schmidt gschmidt AT mit DOT edu -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe AT sourceware DOT cygnus DOT com