1

Microsoft 承认MSVC 通过编译器错误 2688禁止的一个非常特殊的极端情况是非标准行为。有谁知道为什么 MSVC++ 有这个特定的限制?

它涉及同时使用三种语言特性(“虚拟基类”、“协变返回类型”和“可变数量的参数”,根据第二个链接页面中的描述),这些特性在语义上是正交的,并且分别完全支持似乎暗示这不是解析或语义问题,而是 Microsoft C++ ABI 中的一个极端案例。特别是,涉及“可变数量的参数”这一事实似乎(?)表明 C++ ABI 正在使用隐式尾随参数来实现其他两个特性的组合,但不能因为没有固定的位置当函数为 var arg 时放置该参数。

是否有人对 Microsoft C++ ABI 有足够的了解来确认是否是这种情况,并解释这个隐式尾随参数的用途(或者如果我的猜测不正确,还会发生什么)?微软没有记录 C++ ABI,但我知道微软以外的一些人出于各种原因已经完成了与 ABI 匹配的工作,所以我希望有人能解释发生了什么。

此外,微软的文档有点不一致;链接的第二页说:

当虚函数具有可变数量的参数时,不支持将虚基类作为协变返回类型。

但第一页更广泛地指出:

可变参数函数不支持具有多重或虚拟继承的协变返回

有谁知道真实的故事是什么?我可以做一些实验来找出答案,但我猜测实际的极端情况不是这些,确切地说,而是与类层次结构的细节有关,而文件记录者决定掩饰。我猜它与需要在虚拟 thunk 中进行指针调整有关,但我希望比我更了解情况的人能够解释幕后发生的事情。

4

1 回答 1

2

我可以权威地告诉你,MSVC 的 C++ ABI 使用隐式的额外参数来执行在其他 ABI(即安腾)中实现多个单独的函数来处理的事情,所以不难想象这里正在使用一个(或者,如果该案得到支持)。

我不确定在这种情况下发生了什么,但似乎有可能传递一个隐式的额外参数来告诉实现虚函数的 thunk 是否需要向下转换为协变返回类型类(或者,更有可能,是否需要向上转换回基类,因为实际的实现函数可能会返回派生类),并且这个额外的参数放在最后,以便基类可以忽略它(它不知道协变的任何信息返回)。

这意味着当虚拟基类是原始返回类型时总是会出现不受支持的极端情况(因为派生类总是需要一个 thunk),这是第一个引号中描述的;它也会发生在一些(但不是全部)涉及多重继承的情况下(这可能就是为什么它包含在第二个引用中,而不是第一个引用中)。

于 2013-08-31T03:34:11.353 回答