开发者

How does the Linux C++ compiler (and linker) decide where to put typeinfo?

I have a class defined in one h file and implemented in a cpp that is part of one lib (we'll call it libdef).

I have two other libs that have cpp files that include this h file. One of them does dynamic_cast() to this class (we'll call it libdyn) and the other does new for this class (we'll call it libnew).

It seems that in one of these libs there's typeinfo for the type but not in the other:

user@machine> ld --cref libdef.so | grep -E "typeinfo for MyClass"
ld: warning: cannot find entry symbol _start; not setting start address
typeinfo for MyClass libdef.so

user@machine> ld --cref libnew.so | grep -E "typeinfo for MyClass"
ld: warning: cannot find entry symbol _start; not setting start address
typeinfo for MyClass libdef.so

user@machine> ld --cref libdyn.so | grep -E "typeinfo for MyClass"
ld: warning: cannot find entry symbol _start; not setting start address
typeinf开发者_运维百科o for MyClass libdyn.so

As you can see both libdef and libnew use the typeinfo from libdef, but libdyn uses its own typeinfo. Why is that? How does the compiler/linker decide whether to put the typeinfo in one lib or reference it from the other?

I should note that both libnew and libdyn are built with -llibdef.

user@machine> icpc -V
Intel(R) C++ Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 12.0.0.084 Build 20101006
Copyright (C) 1985-2010 Intel Corporation.  All rights reserved.

user@machine> ld -V
GNU ld version 2.17.50.0.6-14.el5 20061020
Supported emulations:
 elf_x86_64
 elf_i386
 i386linux

After some checks I did, it depends on whether the cpp files of the lib "see" a virtual method definition or not.

This code will not result in the typeinfo symbol being in the library:

class SomeClass { public: SomeClass(); virtual void func(); };

This code will produce a typeinfo symbol in the library:

class SomeClass { public: SomeClass() {} virtual void func() {} };

When present, the typeinfo symbol will have vague linkage.


G++ probably defines the typeinfo for the class as a weak symbol, in every object file that needs it. One of the object files in libdef needs it, because it's part of the vtable installed by the constructor. And one of the object files in libdyn needs it, because of the dynamic_cast. If all libnew does is a new, however, it likely wouldn't need it (unless the constructor is inline). At any rate, if it really is a weak symbol, only one of the definitions will be incorporated into the final so or executable; which one is unspecified (but I suspect that it is the first one the linker encounters—which corresponds to what you're seeing).

None of which matters most of the time. (The exception is if you're calling dlopen with RTLD_LOCAL; do this, and dynamic_cast is likely to fail if it executed in an .so other than the one with the object's constructor.)


As others have mentioned, this depends on the C++ implementation. But here is a description of how g++ does it.

Briefly, when possible, g++ defines the class vtable and type_info in the translation unit which defines the first non-inline virtual member of the class.


I think it would be an implementation detail of compiler.

Usually(since virtual table itself is a implementation detail), the virtual table stores a pointer to the type info and I think where the typeinfo is stored is implementation detail of compiler. Most probably it stores the typeinfo in the so which declares the class.


I don't know the implementation details of your compiler and linker, but perhaps it's smart enough not to include the typeinfo where it isn't needed?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜