• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: How is this not a complier error? (dynamic casting problem)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How is this not a complier error? (dynamic casting problem)


  • Subject: Re: How is this not a complier error? (dynamic casting problem)
  • From: Andreas Grosam <email@hidden>
  • Date: Wed, 27 Jul 2005 11:41:38 +0200


On 26.07.2005, at 18:55, Zachary Pincus wrote:

Andreas, Thanks for your help!

I've got some more details about my dynamic-downcast problem.

First, the problem disappears when I switch to gcc3.3 with gcc_select.

Firstly, i need to mention that there is a certain likelyhood that there is actually a problem with the dynamic_cast operator in gcc-4!!


In another thread in this list, "Problem with dynamic_cast & exceptions using GCC 4?", Jesper Papmehl described another problem, that - at the first glance - is apparently a "symbol visibility" problem. However, it turned out - it is not! It actually is a problem with the dynamic cast operator. He already filed a bug to Apple.

Please let me describe what he has dicovered in brief:

std::exception* ep1 = new logic_error("");
std::exception* ep2 = new invalid_argument("");

assert(dynamic_cast<std::logic_error*>(ep1));			// OK
assert(dynamic_cast<std::invalid_argument*>(ep2));	// FAILED!!

That is, for some strange reason, the second down_cast does not work. This only does not work when trying to down_cast "std::invalid_argument", other exception types do work.

I already checked, that the stdlibc++ exports runtime information for std exception classes and especially for std::invalid_argument.



K, back to your problem.

Second, you are right to wonder if the problem has to do with DSO boundaries. My attempts to make complete test cases (as you suggest below) did not re-create the bug. In fact, I *only* see the error if the Image object was passed across a DSO boundary. If I make a new one in situ, no error.


If you define a class which later may be an operand in a dynamic_cast operator which is called from within another DSO - or if this is a class which is thrown in an exception and the catch expression is in another DSO or crosses DSOs, you should (need to) export RTTI symbols.
RTTI will be exported only when the class is exported (gcc-4.0.0). (see below how to ensure to export the class).



Now, I'm fairly sure that the RTTI information is being exported. I don't think I've any of the "symbols hidden by default" flags on. Moreover, the RTTI information seems to exist for the Image object that can't be properly downcast, since I can call typeid and get the correct name for the pointed-to object.
Well, now since there might be a problem with the dynamic_cast operator, you really need to double check your problem and verify if your problem is really a dynamic_cast problem. If so, we have a serious defect in gcc-4, and i really would appreciate if this get more attention from the folks at Apple.


Is there a better run-time check to make sure that the RTTI information was properly exported?
hm, typeid may access the mangled name of the type, which would be not there if RTTI is not there.
You can also use the nm tool, to check which symbols have been exported. For gcc-4 RTTI symbols start with _ZTI.
Please read the man page for nm and make some tests with small sources.


In order to be sure that a class will be exported, I recommend to use macros which explicitly define the visibility attribute. So, in order to be sure to export a certain class you would write:

class EXPORT MyClass
{
	// ...
};


The macro EXPORT expands to the visibility attribute - if this is supported by the compiler:
#if ...
#define EXPORT __attribute__ ((visibility("default")))
#else


In another mail, I already described how to define these macros.



Also, how do I force this information to be exported -- just declare a class "extern"?
For gcc-4: no. For gcc-4 you need to use the visibility attribute in the class definition:
class __attribute__ ((visibility("default"))) MyClass
{
public:
virtual ...
// ...
};


Then, the class is always exported, no matter which compiler options are set.


For gcc-3.3, you need no visibility attribute, all symbols (classes) are exported from the compiler:
class MyClass
{
public:
virtual ...
// ...
};


(Note, for gcc-3 you can use an "exported symbols file" to limit the exported symbols - but its usage is cumbersome - to be politely.)


For more information, please read:
<http://developer.apple.com/documentation/DeveloperTools/Conceptual/ CppRuntimeEnv/Articles/SymbolVisibility.html>
see also
<http://gcc.gnu.org/wiki/Visibility>


In case there is some hidden interaction causing symbols not to be exported by default, I'd like to see if forcing them to be exported works.
Note, per default the compiler exports all symbols.
However, XCode (or you) may set build settings which override the compiler defaults - which causes XCode to emit compiler options.


There are two compiler options which control symbol visibility:
-fvisibilty=  hidden | default
-fvisibility-inlines-hidden

In XCode the corresponding build settings are:
Symbols Hidden by Default
Inline Functions Hidden

If you check "Symbols Hidden by Default" in the build setttings, XCode emits "-fvisibilty=hidden" as a compiler option.
Likewise, if you check "Inline Functions Hidden", XCode emits "-fvisibility-inlines-hidden".




Now, I'm combing through the exact GCC flags that the project is actually compiled with, but I see nothing suspicious. Also, the fact that changing to gcc3.3 without changing any other settings makes things work all of a sudden worries me -- do gcc3.3 and gcc4.0 differ in how they handle exported symbols?
Yes - although the compiler defaults yield to the same behavior. This will be explained in detail in the documentation.


Regards Andreas



Thanks,

Zach Pincus
Program in Biomedical Informatics and Department of Biochemistry
Stanford University School of Medicine


On Jul 26, 2005, at 4:28 AM, Andreas Grosam wrote:


On 26.07.2005, at 03:45, Zachary Pincus wrote:


Hello,

I'm running into a problem in my C++ code (which uses RTTI and dynamic_cast) which I can only account to be a g++ compiler error.


snip

the result of the downcast looks strange.

Can you test whether a dynamic downcast is successful using these classes:

template <int K>
class base
{
public:
    enum { value = K };
    virtual ~base() {}
};

template <typename T, int K>
struct derived : base<K>
{
    derived(const T& v = T()) : x(v) {}

    T x;
};


On XCode 1.5 (gcc-3.3) and XCode 2.1 (gcc-4.0.0), the dynamic_cast works as expected.
Adding a namespace, does not break it, too.




So, one oddity I notice is that the run-time type of the dereferenced pointers is NOT const, even though it should be.



It seems, the mangled names do not contain a qualifier for non pointer types, that is:


typeid(const T).name() is_equal typeid(T).name()
typeid(volatile T).name() is_equal typeid(T).name()

where T is a non-pointer type.

This condition evaluates to true also:
( typeid(T) == typeid(const T) )

IMO, this treatment is questionable.

That does not mean, that the compiler is unable to distinguish this types, though.



But I see no reason that imageBaseP, which points to an itk::Image object, couldn't be down-cast to the same! Any thoughts?


IMO, the downcast should work.
The base class needs to be a polymorphic class of course, the compiler would complain otherwise.
The types need to be complete, that means, include everything necessary to instantiate a complete object. But i guess, the compiler would also complain, otherwise.


Are the objects instantiated in the same library (DSO)? Is the call to operator dynamic_cast in the same DSO?
If "No", you need to ensure that RTTI information is exported accross DSOs - means your types (template classes) shall be exported.


hm, no more thoughts.

Andreas




_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
email@hidden


This email sent to email@hidden






_______________________________________________ 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
  • Follow-Ups:
    • Re: How is this not a complier error? (dynamic casting problem)
      • From: Zachary Pincus <email@hidden>
References: 
 >How is this not a complier error? (dynamic casting problem) (From: Zachary Pincus <email@hidden>)
 >Re: How is this not a complier error? (dynamic casting problem) (From: Andreas Grosam <email@hidden>)
 >Re: How is this not a complier error? (dynamic casting problem) (From: Zachary Pincus <email@hidden>)

  • Prev by Date: Warning question - correct or not?
  • Next by Date: Re: Warning question - correct or not?
  • Previous by thread: Re: How is this not a complier error? (dynamic casting problem)
  • Next by thread: Re: How is this not a complier error? (dynamic casting problem)
  • Index(es):
    • Date
    • Thread