MSVC is confused by the same-named source file! If the code is split into t1.cpp:
#include <typeinfo> namespace { struct Foo { int a; }; } const std::type_info &tu1() { return typeid(Foo); } and t2.cpp: #include <typeinfo> namespace { struct Foo { float b; }; } const std::type_info &tu1(); const std::type_info &tu2() { return typeid(Foo); } extern "C" void printf(const char *, ...); int main() { printf("tu1() == tu2(): %d\n", tu1() == tu2()); } then (with MSVC 2012) : sh-3.1$ cl -c t1.cpp && cl -c t2.cpp && cl t1.obj t2.obj && ./t1.exe tu1() == tu2(): 0 sh-3.1$ cl t1.cpp t2.cpp && ./t1.exe tu1() == tu2(): 0 (I tested both forms to see it's not related to everything compiled at once) However, your point IS valid, since when the actual names are printed (names which will be used in the strcmp): printf("tu1().name: %s\n", tu1().name()); printf("tu2().name: %s\n", tu2().name()); with MSVC we get tu1() == tu2(): 0 tu1().name: struct `anonymous namespace'::Foo tu2().name: struct `anonymous namespace'::Foo and with gcc: tu1() == tu2(): 0 tu1().name: *N12_GLOBAL__N_13FooE tu2().name: *N12_GLOBAL__N_13FooE So when comparing type ids only, we'll miss exceptions from DLLs, while if we compare type names as well we may catch a same-named class coming from the same namespace even it's actually something different. Given only these two options (maybe there is a better solution?), I'd still go with the first, since many C++ DLL libraries throw exceptions which *must* be caught, else the library is not usable. This is a showstopper. OTOH, same-named classes - in the same namespace - in different TU are probably uncommon and throwing them around where they might be confused is probably even less common. Yaron 2013/11/23 Reid Kleckner <r...@google.com> > One other thing to think about is: are typeid names of internal types > unique? MSVC seems to get it wrong, as in this prints 1: > > $ cat t.cpp > #include <typeinfo> > #ifdef CONFIG_1 > namespace { struct Foo { int a; }; } > const std::type_info &tu1() { return typeid(Foo); } > #else > namespace { struct Foo { float b; }; } > const std::type_info &tu1(); > const std::type_info &tu2() { return typeid(Foo); } > extern "C" void printf(const char *, ...); > int main() { > printf("tu1() == tu2(): %d\n", tu1() == tu2()); > } > #endif > > $ cl -c t.cpp && cl -c -DCONFIG_1 t.cpp -Fot2.obj && cl t.obj t2.obj && > ./t.exe > ... > tu1() == tu2(): 1 > On Fri, Nov 22, 2013 at 1:48 PM, Yaron Keren <yaron.ke...@gmail.com> wrote: > OK, fixed. > > > > 2013/11/22 Reid Kleckner <r...@google.com> > >> Yes, this is just a property of COFF, so it should be _WIN32. > > > > On Fri, Nov 22, 2013 at 5:18 AM, Yaron Keren <yaron.ke...@gmail.com>wrote: > >> On Windows, typeids are different between DLLs and EXEs, so comparing >> type_info* will work for typeids from the same compiled file but fail for >> typeids from a DLL and an executable. Among other things, exceptions are >> not caught by handlers since can_catch() returns false. >> >> Defining _LIBCXX_DYNAMIC_FALLBACK does not help since can_catch() calls >> is_equal() with use_strcmp=false so the string names are not compared. >> >> This patch compares typeids first (cheap) and only they are different >> calls strcmp. >> >> If libcxxabi with Visual C++ has the same problem, __MINGW32__ should be >> replaced with _WIN32 in both locations. >> >> Yaron >> >> >> _______________________________________________ >> cfe-commits mailing list >> cfe-commits@cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >> >> >
_______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits