- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello.This code throws an exception when compiled with ICC 12.1.5 (works fine with MSVC and GCC):[cpp]class A { public: virtual void _dummy() { } }; class B: virtual public A { }; class C: virtual public A, public B { }; int main() { auto c = new C; auto a = dynamic_cast< A * >( c ); auto b = dynamic_cast< B * >( c ); auto ca = dynamic_cast< C * >( a ); // ok auto cb = dynamic_cast< C * >( b ); // std::__non_rtti_object return 0; } [/cpp] The culprit seems to be the "class B: virtual public A" part. Just "class B: public A" works without exceptions.----Regards,Vladimir
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Brandon,
were you able to reproduce the issue?
----
Vladimir
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Did you compile the test-case without modifications? I could not compile... So, please take a look at amodified test-case:
[cpp] ... C *pC = new C; A *pA = dynamic_cast< A * >( pC ); B *pB = dynamic_cast< B * >( pC ); C *pCA = dynamic_cast< C * >( pA ); C *pCB = dynamic_cast< C * >( pB ); ...[/cpp]I'm still investigating and will provide some technical details later.
Best regards,
Sergey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Vladimir,
In your original post you've stated that the test case"...works fine with MSVC...". I understood that you've compiled it with
some version of Visual Studio. Did you use 2005, 2008, 2010 or 2012 vesrion?
In case ofMicrosoft C++ compiler and Visual Studio 2005 I can't compile
...
auto c = new C;
...
because it doesn't support C++11. I simply wanted to verify howthe testworks when it is compiled with Microsoft C++ compiler.
Could you provide more details on your software development environment? Thanks in advance.
Best regards,
Sergey
PS: Here are compilation errors I have:
..\PrtTests.cpp(5710) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
..\PrtTests.cpp(5710) : error C2440: 'initializing' : cannot convert from 'C *' to 'int'
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I hope thata modified test-case for a 'dynamic_case' C++ operator will be useful for you ( it is amore generic ):
...
class A
{
public:
virtual void Method( void )
{
printf( "A::Method\n" );
};
};
class B: virtual public A
{
public:
virtual void Method( void )
{
printf( "B::Method\n" );
};
};
class C: virtual public A, public B
{
virtual void Method( void )
{
printf( "C::Method\n" );
};
};
class D
{
public:
virtual void Method( void )
{
printf( "D::Method\n" );
};
};
...
C *pC = new C;
A *pA = dynamic_cast< A * >( pC );
printf( "Object A is%sinitialized\n", ( pA !=NULL ) ? " " : " NOT " );
B *pB = dynamic_cast< B * >( pC );
printf( "Object B is%sinitialized\n", ( pB !=NULL ) ? " " : " NOT " );
C *pCA = dynamic_cast< C * >( pA );
printf( "Object C is%sinitialized\n", ( pCA !=NULL ) ? " " : " NOT " );
C *pCB = dynamic_cast< C * >( pB );
printf( "Object C is%sinitialized\n", ( pCB !=NULL ) ? " " : " NOT " );
D *pD = dynamic_cast< D * >( pC );
printf( "Object D is%sinitialized\n", ( pD !=NULL ) ? " " : " NOT " );
...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Have you noticed that I've added a new class D andthen tried to castthe pointerof the class Cto the pointer ofclassD?
A very important feature of the 'dynamic_cast'isthat itshould not cast fromtypeC to type D andthepointer to the object oftype D
must be equal toNULL.
However, I think that something is wrong with Intel C++ compiler because your original test-case is very generic even if it uses
some C++11 features. I wonder if thereissome problem related to support ofC++11 features in the compiler?
Best regards,
Sergey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Dynamic cast from B* to C* raises an exception when B does not declare/define any virtual functions, but does NOT fail if it does (concrete or pure functions, doesn't matter).
- Likewise, dynamic cast from C* to D* raises an exception when C declares/defines no virtual functions, and works fine otherwise.
- The issue disappears if we add a virtual destructor to A (and, by extension, implicitly generated virtual destructors to its descendants).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[SergeyK] I've done a verification with two more C++ compilers ( MinGW & Borland )andthere are no anyissues or problems.
- Dynamic cast from B* to C* raises an exception when B does not declare/define any virtual functions, but does NOT fail if it does (concrete or pure functions, doesn't matter).
- Likewise, dynamic cast from C* to D* raises an exception when C declares/defines no virtual functions, and works fine otherwise.
[SergeyK] It shouldn't raise any exceptions and it should assign a valueNULL to apointer of type D.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
C *pC = new C;
A *pA = dynamic_cast< A * >( pC );
printf( "Object A is%sinitialized\n", ( pA !=NULL ) ? " " : " NOT " );
B *pB = dynamic_cast< B * >( pC );
printf( "Object B is%sinitialized\n", ( pB !=NULL ) ? " " : " NOT " );
C *pCA = dynamic_cast< C * >( pA );
printf( "Object C is%sinitialized\n", ( pCA !=NULL ) ? " " : " NOT " );
C *pCB = dynamic_cast< C * >( pB );
printf( "Object C is%sinitialized\n", ( pCB !=NULL ) ? " " : " NOT " );
D *pD = dynamic_cast< D * >( pC );
printf( "Object D is%sinitialized\n", ( pD !=NULL ) ? " " : " NOT " );
...
use a"default" cast, like:
...
A *pA = ( A * )pC;
printf( "Object A is%sinitialized\n", ( pA !=NULL ) ? " " : " NOT " );
B *pB = (B * )pC;
printf( "Object B is%sinitialized\n", ( pB !=NULL ) ? " " : " NOT " );
C *pCA = ( C * )pA;
printf( "Object C is%sinitialized\n", ( pCA !=NULL ) ? " " : " NOT " );
C *pCB = ( C * )pB;
printf( "Object C is%sinitialized\n", ( pCB !=NULL ) ? " " : " NOT " );
D *pD = (D * )pC;
printf( "Object D is%sinitialized\n", ( pD !=NULL ) ? " " : " NOT " );
...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I really don't understand whyIntel C++ compilerneeds RTTI for the test-case.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Gentlemen,
the original test case still fails on ICC 2013 update 2, command line (with just "icl.exe test.cpp"), or under MSVS 2012, x86 and x64. Any luck reproducing the issue?
----
Regards,
Vladimir
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you, Sergey. I'm somewhat surprised to see a malloc in dynamic_cast, but the end result is the same: the "__non_rtti_object" exception. In my case (ICC 13.1.0 on MSVS 2012), the exception has been originally caused by a nullptr dereference in FindCompleteObject, just like with ICC 12.1.5.
It's a shame that, other than a single "can't reproduce" note (probably caused by using a linux version or something), Intel people seem to ignore this report. I wonder if it will take a new thread to draw attention.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page