On linux x86, using the following 2 little sources files : ---------- 1.C -------------------- #include <typeinfo> class A { public: A() {} }; extern void foo(const std::type_info&); int main() { foo(typeid(A*)); return 0; } ----------------------------------- ---------- 2.C -------------------- #include <iostream> #include <typeinfo> class A; void foo(const std::type_info& t) { if (t == typeid(A*)) { std::cout << "OK\n"; } else { std::cout << "KO\n"; } } ----------------------------------- and compiling with "g++ 1.C 2.C" gives me KO output. This means that the comparison of the type_info passed to foo and the one computed by typeid(A*) where A* is an incomplete type failed. In the binary there are 2 type_info symbols for A* : % nm a.out| grep TIP1A 0804884c r _ZTIP1A 0804882c V _ZTIP1A I tried this test with many compilers and it worked with g++ 3.2 and failed with g++ 3.3, 3.4 and pre4.0 (with the same binutils). Precise versions : % gcc-3.2 --version gcc-3.2 (GCC) 3.2.3 (Debian) % gcc-3.3 --version gcc-3.3 (GCC) 3.3.5 (Debian 1:3.3.5-8ubuntu2) % gcc-3.4 --version gcc-3.4 (GCC) 3.4.4 20050209 (prerelease) (Debian 3.4.3-9ubuntu3) % gcc-4.0 --version gcc-4.0 (GCC) 4.0.0 20050301 (prerelease) (Debian 4.0-0pre6ubuntu6)
Hmm, this works without weak symbols.
Andrew, I don't fully get what you mean and seeing no activity on this bug makes me wonder if you expect some feedback from me... Experimenting based on your comment I tried using -fno-weak, but it doesn't work nor seems recommended. So I wonder if what I see is a real bug, me misusing C++ or maybe a bug in the packages I use.
(In reply to comment #2) > Andrew, I don't fully get what you mean and seeing no activity on this bug makes > me wonder if you expect some feedback from me... Experimenting based on your > comment I tried using -fno-weak, but it doesn't work nor seems recommended. So I > wonder if what I see is a real bug, me misusing C++ or maybe a bug in the > packages I use. No I mean this works on targets without weak symbol support like say openbsd or older versions of gcc on darwin (Mac OS X). I don't know the C++ rules to say this is correct or not.
FWIW, is also "KO" with ICC 9.0.
Nathan, can you have a look to this PR? (Googling reveals a lot of hits for nathan & typeid ;) Thanks in advance.
I nearly forgot that I submitted this bug report... I got myself a version of the C++ standard since I submitted that, and I just had a look at the part describing typeid : 5.2.8.4 reads : "When typeid is applied to a <i>type-id</i>, [...]. If the type of the type-id is a class type or a reference to a class type, the class shall be completely-defined." I believe A* in 2.C qualifies a a reference to a not-completely defined class type, and thus shouldn't be passed to std::typeid. I'm not an expert in standard reading, but it seems to me that the current behaviour isn't really a bug. If possible, I would be glad to see a warning emited by GCC in that case, because I hit that problem in real-world code (generic callback system using boost::any behind the scenes) and I spent hours finding out what was happening. Maybe I should suggest adding a concept check to the boost code if it is possible to detect it.
(In reply to comment #6) > I nearly forgot that I submitted this bug report... > [...] At first, I was under the same impression - not a bug - however, I'm not sure anymore... Have also a look to the ABI: http://www.codesourcery.com/cxx-abi/abi.html section 2.9.3, and then the last sentence of 2.9.5/7... In your example the NTBS addresses (returned by type_info::name()) seem equal... ?!?
(In reply to comment #7) > section 2.9.3, and then the last sentence of 2.9.5/7... In your example the > NTBS addresses (returned by type_info::name()) seem equal... Sorry, I was wrong! The names, the strings, are equal, but the *addresses* are not! Yes, it seems invalid...
Ok, I'm closing this, because the ABI, if not the standard, seems really unequivocal. About the warning, I don't know, probably it's not that easy to implement, I also looked for it, but no other compiler I have at hand apparently is able to emit it...
A * is not a reference to an incomplete type, but a pointer to one, so 5.2.8.4 does not apply. I'm fairly certain the correct output should be 'OK'. The two type id objects should have different addresses (one should be weak, one should be local static). The typeid strings should have the same address (and be emitted weak)
Ah, ah, the addresses should be equal in the first place! Ok, thanks for looking into this.
When I read the standard, I thought that 'reference to a class type' was used in a sort of general way covering pointers and C++ references. I interpreted this that way because I don't see what difference it could make to a compiler and/or a developper that typeid(A*) is valid while typeid(A&) isn't. So just for my personal knowledge, what could be the rationale behind this special casing ?
Nathan, any news about this PR? Thanks.
Subject: Bug 20647 Author: nathan Date: Sun Oct 22 16:07:41 2006 New Revision: 117957 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=117957 Log: cp/ PR c++/20647 * rtti.c (tinfo_base_init): The type info string is always global. testsuite/ PR c++/20647 * g++.dg/abi/rtti3.C: New. Added: trunk/gcc/testsuite/g++.dg/abi/rtti3.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/rtti.c trunk/gcc/testsuite/ChangeLog
2006-10-22 Nathan Sidwell <nathan@codesourcery.com> PR c++/20647 * rtti.c (tinfo_base_init): The type info string is always global.
Subject: Bug 20647 Author: nathan Date: Mon Oct 23 07:42:02 2006 New Revision: 117970 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=117970 Log: cp/ PR c++/20647 * rtti.c (tinfo_base_init): The type info string is always global. testsuite/ PR c++/20647 * g++.dg/abi/rtti3.C: New. Added: branches/gcc-4_1-branch/gcc/testsuite/g++.dg/abi/rtti3.C Modified: branches/gcc-4_1-branch/gcc/cp/ChangeLog branches/gcc-4_1-branch/gcc/cp/rtti.c branches/gcc-4_1-branch/gcc/testsuite/ChangeLog
Subject: Bug 20647 Author: nathan Date: Tue Oct 24 08:38:26 2006 New Revision: 117999 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=117999 Log: cp/ PR c++/20647 * rtti.c (tinfo_base_init): The type info string is always global. testsuite/ PR c++/20647 * g++.dg/abi/rtti3.C: New. Added: branches/gcc-4_2-branch/gcc/testsuite/g++.dg/abi/rtti3.C Modified: branches/gcc-4_2-branch/gcc/cp/ChangeLog branches/gcc-4_2-branch/gcc/cp/rtti.c branches/gcc-4_2-branch/gcc/testsuite/ChangeLog
fixed on mainline, 4.1 & 4.2
Adjust target milestone.