Re: frameworks, dynamic_cast and gcc 4.0
Re: frameworks, dynamic_cast and gcc 4.0
- Subject: Re: frameworks, dynamic_cast and gcc 4.0
- From: Andreas Grosam <email@hidden>
- Date: Tue, 23 Aug 2005 17:38:49 +0200
On 23.08.2005, at 16:55, Steve Baxter wrote:
Hi Andreas,
On 23 Aug 2005, at 14:43, Andreas Grosam wrote:
On 22.08.2005, at 17:56, Steve Baxter wrote:
Hi Stephan,
I ran into a problem like this as well. The problem seems to be a
difference in implementation between dynamic_cast in GCC 4.0 and in
most other compilers (or at least CodeWarrior and VC++).
It seems that GCC 4.0 treats classes linked in different shared
units as different, even if they have the same name. There is some
good information here:
http://gcc.gnu.org/faq.html#dso
Yeah, but it is also explained that RTTI symbols *have* to be
resolved propperly at load time. That means, if you perform a
dynamic_cast in DSO S1 you need to link against the DSO S2, where the
class (and all the type info) is defined and you also need to make
the RTTI symbols accessible in DSO S2.
Then, only one instance of RTTI is *active*.
It seems that if you load plugins dynamically, RTTI symbols may not be
resolved uniquely. I understand that the specification that GCC has
adopted assumes that RTTI symbols are resolved, however in the real
world they may not be. It should deal properly with this case - I
suspect you can define __GXX_MERGED_TYPEINFO_NAMES to 0 to achieve
this.
It should be noted that both CW and VC++ compare type_info by name,
not by address (for exactly this reason).
You will see this problem if the same source file is linked or
included in more than one DSO (dynamic shared object).
Shouldn't i then get link errors (duplicate symbols)??
So then, you are doing something wrong. As mentioned, you need to
link against the DSO where the class is defined, instead of including
the source module into the calling DSO.
No link error - the DSOs do not link against each other.
In case of plugins, you will not do it (and dynamic cast will not work
here).
But for other shared libs, which will be linked at load time, you *need
to* link against it.
More irritatingly, you can run into this problem with fully-inline
classes - if the class header is included in more than one DSO, it
will end up with two type_info copies, one in each DSO (this can
happen very commonly with template code).
These constructs are indeed more complicated, especially dealing with
templates. However, if not otherwise stated explicitly in bold face,
you can rely on the tools! ;-)
The problem here is, that you don't get linker errors, when you just
not link against the DSO where the class template has been
instantiated. But you need to.
I'm afraid I don't think the tools work properly - the simple fact is
that code that works properly in VC++ and CW does not work in XCode -
it compiles and links, but fails at runtime (the worst possible sort
of error).
I agree, this is painful. But i'm unsure whether we can say the tools
work not properly. At least they work as described (i this case).
These constructs are said to have "vague linkage":
http://developer.apple.com/documentation/DeveloperTools/gcc-4.0.0/
gcc/Vague-Linkage.html
The reason for the problem seems to be that the GCC writers changed
GCC so that type_info was checked for equality by comparing
addresses rather than really comparing for equality. Two type_infos
with different addresses are always considered to be different even
if they are in fact identical. This was done for performance
reasons - a pointer comparison is (obviously) faster than a string
compare.
That is true. And this works only under the assumption that the
symbols (or better objects) have been resolved propperly. Then, there
is only one *active* object, and this is the correct one.
As I say, this is not necessarily true in the real world, however much
the GCC developers would like it to be true in an academic sense. I
would argue that the optimisation they have tried to do is flawed.
Firstly, you should do what is required - not what are you usually used
to do.
But yes, the optimization is questionable. Even more, that this can be
easily fixed without a significant performance hit.
I suspect this works OK within a single DSO - the linker discards
duplicate copies of the type_info constructs so you end up with only
one.
Yes, because the symbols will be resolved at link time, and only one
will be made the *active* object.
When you use shared libs, resolving occurs at load time, but the
effect is the same: one and only one object will be made the active
one.
In case of RTTI, you also need to ensure that the selected active
object is the correct one, means, firstly you need to link against
the DSO where it is defined, and you also need to export the symbols.
Then, and only then, the dynamic linker can resolve the correct
symbol at load time.
I am not sure what you are supposed to do in multi-DSO applications
where the same template or inline class might be used in several
DSOs - I would want then to be treated as identical, but the GCC
runtime would not do this. This is probably going to be a
show-stopper for us - this works fine in VC++ and CodeWarrior though
Again, ensure you link against the DSO where the class is defined -
and do *not* include source modules in more than one DSO which are
used in your application.
Unless you only use dynamic_cast to check the type, but also call
member functions of this object, you need to link against this DSO
anyway!
It is perfectly possible and permissible to call virtual methods of an
object without linking to it - all you need is the vtable. A virtual
call is, after all, a call by function pointer.
I'm unsure about that.
If the vtable which is referenced is instantiated in DSO 2 where the
derived class has been defined, you must link your App (the caller)
against DSO 2, not to DSO 1 where the base classes are defined.
However, you need not link against DSO 1. (because DSO 2 is already
linked to DSO 1 and the linker resolves the symbols).
Imagine: if DSO 1 does not link to other DSOs, DSO App only links
against DSO 1, then where is the image containing the code for DSO 2?
It has never been specified as a path to resolve symbols, and the
dynamic linker will not find the required symbols. (or it will take the
wrong local ones which happenly have been created in DSO App without
issuing link errors!).
Andreas
Cheers,
Steve.
Stephen Baxter
Software Development Manager
Improvision
email@hidden
+44-2476-692229
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden