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

发布于 2024-08-13 07:33:32 字数 756 浏览 11 评论 0原文

Andrei Alexandrescu现代 C++ 设计

typeid返回的对象有 静态存储,因此您不必 担心终身问题。

安德烈继续说道:

该标准不保证 每次调用,例如 typeid(int) 返回对相同内容的引用 type_info 对象。

尽管标准不保证这一点,但在常见编译器(例如 GCC 和 Visual Studio)中如何实现这一点?

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

是否有时会出现 &typeid(T) != &typeid(T)

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

Andrei Alexandrescu writes in Modern C++ Design:

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

Andrei continues:

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

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

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?

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

音盲 2024-08-20 07:33:32

有时 &typeid(T) != &typeid(T) 吗?

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

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

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 中

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

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

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

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

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

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.

九歌凝 2024-08-20 07:33:32

标准有时会未指定某些行为,以便给予实现一定的自由。在这种情况下,TypeID 的管理方式由编译器实现决定,您只需给出一组规则(本质上:不必关心如何分配内存)。

您需要能够根据内存地址比较 TypeId 是否有任何特殊原因? TypeId 已经覆盖 == 和 != 以便为您提供比较它们的能力,并提供可用于唯一标识它们的 name() 。

如果您有《C++ 编程语言》(Bjarne Stroustrup),第 15 章有很多有关处理类层次结构的详细信息。也许您可以在那里找到另一种解决方案?

Standards sometimes leave certain behavior unspecified in order to give implementations some freedom. In this case, how TypeIDs are managed is being left up to the compiler implementation and you're simply being given a set of rules (essentially: don't concern yourself with how memory for this is being allocated).

Is there any particular reason why you need to be able to compare TypeIds based upon their memory address? TypeIds already override == and != in order to provide you with the ability to compare them, and provide a name() that might be used to identify them uniquely.

If you've got The C++ Programming Language (Bjarne Stroustrup) available, chapter 15 has a lot of details about handling class hierarchies. Maybe you might find another solution there?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文