2013-08-31 45 views
1

MSVC通过Compiler Error 2688禁止的非常特殊的角落案例是admitted by Microsoft是非标准行为。有谁知道为什么MSVC++有这个特定的限制?MSVC编译器错误C2688:Microsoft C++ ABI转角案例问题?

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

有没有人有足够的Microsoft C++ ABI知识来确认是否是这种情况,并解释这个隐含的结尾参数用于什么(或者还有什么事情发生,如果我的猜测不正确)? C++ ABI没有被微软记录下来,但我知道微软以外的一些人为了与各种原因匹配ABI而做了很多工作,所以我希望有人能够解释发生了什么。

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

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

,但在第一页更广泛地说:

多个或虚继承协变的回报不支持可变参数的函数

有谁知道真正的故事是什么?我可以做一些实验来发现,但我猜测实际的角落案例既不是这些,也不是确切的,而是与文档人员决定遮盖的类层次的细节有关。我的猜测是,它需要在虚拟thunk中进行指针调整,但我希望能够比我更深入地了解情况的人可以解释背后的情况。

回答

2

我可以告诉你,MSVC的C++ ABI使用隐式额外参数来做其他ABI(即Itanium)实现多个独立函数来处理的事情,因此不难想象这里使用了一个(或如果支持的话)。

我不知道在这种情况下发生了什么,但似乎合理的是传递一个隐含的额外参数来告知实现虚拟函数的thunk是否需要向协变返回类型类降级(或,更有可能的是,是否需要向上返回到基类,因为实际的实现函数可能会返回派生类),并且这个额外的参数会持续下去,以便它可以被基类忽略(它不知道任何关于协变的回报)。

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