typeid 什么时候可以为同一类型返回不同的 type_info 实例?

Andrei Alexandrescu 在 现代C++设计:

typeid 返回的对象有静态存储,所以你不必担心终身问题.

The objects returned by typeid have static storage, so you don't have to worry about lifetime issues.

安德烈继续:

标准不保证每次调用,比如说,typeid(int)返回相同的引用type_info 对象.

The standard does not guarantee that each invocation of, say, typeid(int) returns a reference to the same type_info object.

虽然标准不保证这一点,但在 GCC 和 Visual Studio 等常见编译器中是如何实现的?

Even though the standard does not guarantee this, how is this implemented in common compilers, such as GCC and Visual Studio?

假设 typeid 没有泄漏(并且每次调用都返回一个新实例),它是每个应用程序、每个翻译单元、每个 dll/so 一个表",还是完全不同的东西?

Assuming typeid does not leak (and return a new instance every call), is it one "table" per application, per translation unit, per dll/so, or something completely different?

是否有&typeid(T) != &typeid(T)的时候?

我主要对 Windows 编译器感兴趣,但也感谢任何有关 Linux 和其他平台的信息.

I'm mainly interested in compilers for Windows, but any information for Linux and other platforms is also appreciated.

推荐答案

是否有 &typeid(T) != &typeid(T) 的时候?

Are there times when &typeid(T) != &typeid(T)?

我主要对 Windows 编译器感兴趣,但也感谢任何有关 Linux 和其他平台的信息.

I'm mainly interested in compilers for Windows, but any information for Linux and other platforms is also appreciated.

是的.因此,在 windows 下 DLL 不能有未解析的符号.如果你有:

Yes. Under windows DLL can't have unresolved symbols, thus. If you have:

foo.h

struct foo { virtual ~foo() {} };

dll.cpp

#include "foo.h"
...
foo f;
cout << &typeid(&f) << endl

main.cpp

#include "foo.h"
...
foo f;
cout << &typeid(&f) << endl

会给你不同的指针.因为在加载 dll 之前 typeid(foo) 应该存在在 dll 和主 exe 中

Would give you different pointers. Because before dll was loaded typeid(foo) should exist in both dll and primary exe

此外,在 Linux 下,如果未使用 -rdynamic(或 --export-dynamic)编译主可执行文件,则 typeid 将解析为可执行文件中的不同符号,并且在共享对象中(在 ELF 平台下通常不会发生),因为在链接可执行文件时进行了一些优化――删除了不必要的符号.

More then that, under Linux, if main executable was not compiled with -rdynamic (or --export-dynamic) then typeid would be resolved to different symbols in executable and in shared object (which usually does not happen under ELF platforms) because of some optimizations done when linking executable -- removal of unnecessary symbols.

相关文章