#152 GCC 3.1 dynamic_cast fails with DLLs

gcc (462)

When attempting to use dynamic_cast in an
executable to cast a base class pointer to an instance
produced in a DLL to a derived class dynamic_cast
fails, returning zero. e.g.

class cFoo { ... };
class cBar : public cFoo { ... };

cFoo* pfoo = CreateBarInDLLAndCastToFoo();
cBar* pbar = dynamic_cast<cBar*>(pfoo);

pbar ends up zero.

The same code works as expected when compiled into
a single executable or when I revert to gcc 2.95.3 and
an older version of binutils.

Attached is a simple test case demonstrating the
problem. main.cpp is the executable, while foobar.cpp
is built into a DLL. Doing a "make test" builds a static
version static.exe and dynamic version dll.exe, then
runs both. Sample output is included for make test
with gcc 2.95.3 (old.out) and gcc 3.1 (new.out).

If the test works properly, the printed output for
the "Bar pointer" will be non-zero in both static and
DLL cases.

Note: The Makefile as it is builds with the -v flag. I also
only used it under bash and with working versions of
rm and echo available.


  • Colin Peters

    Colin Peters - 2002-06-12

    Test case files and output

  • Danny Smith

    Danny Smith - 2002-06-13

    Logged In: YES

    Thanks for the report. This will be a challenge.

    typinfo implementation has changed quite a bit.
    Compare the assemby code for main.cpp in 2.95.3 and

    2.95: typeinfo is accessed through function

    3.1: typinfo variable accessed directly

    DATA gets prefixed with _imp_ in dll lib so maybe the
    problem is in .linkonce not working.
    In 2.95 with access through .linkonce function there is
    no problem because function name isn't decorated
    I've got some digging to do.


  • Danny Smith

    Danny Smith - 2002-06-16

    Logged In: YES

    Actually gcc FAQ has a section entitled:
    "dynamic_cast, throw, typeid don't work with shared
    libraries" but it seems to be talking about platforms
    that have weak linkage and use addresses to determine
    type equality. w32 targets still uses string
    comparisons. Any ideas?


  • Luke Dunstan

    Luke Dunstan - 2002-06-17

    Logged In: YES

    In tinfo.cc:


    // We can't rely on common symbols being shared between
    shared objects.
    bool std::type_info::
    operator== (const std::type_info& arg) const
    return (&arg == this) || (__builtin_strcmp (name (), arg.name
    ()) == 0);


    In <typeinfo>:

    #if !__GXX_WEAK__
    // If weak symbols are not supported, typeinfo names are
    not merged.
    // On platforms that support weak symbols, typeinfo names
    are merged.

    However, in cppinit.c:

    _cpp_define_builtin (pfile, "__GXX_WEAK__ 1");
    _cpp_define_builtin (pfile, "__GXX_WEAK__ 0");

    And in defaults.h:

    /* This determines whether or not we support link-once
    semantics. */
    #define SUPPORTS_ONE_ONLY 1
    #define SUPPORTS_ONE_ONLY 0

    So possibly GXX_WEAK is a misnomer because it is defined
    when linkonce is supported, not weak symbols.

    Test this for Mingw with:

    $ echo __GXX_WEAK__ | cpp -x c++
    # 1 "<stdin>"
    # 1 "<built-in>"
    # 1 "<command line>"
    # 1 "<stdin>"

  • Danny Smith

    Danny Smith - 2002-08-01
    • status: open --> pending-fixed
  • Danny Smith

    Danny Smith - 2002-08-01

    Logged In: YES

    Fixed in cygwin-mingw-gcc-3_2-branch of FSF CVS

  • Danny Smith

    Danny Smith - 2002-08-26
    • status: pending-fixed --> closed-fixed
  • Danny Smith

    Danny Smith - 2002-08-26

    Logged In: YES

    The problem you report has caused modification in some fashion in the official CVS for the given package. The w32api and
    mingw-runtime official CVS reside in the winsup CVS directory tree for Cygwin. Those package CVS trees are periodically
    merged into the MinGW CVS tree. If you still find problems then please open a new report.


Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

No, thanks