MSVC通过Compiler Error 2688禁止的特定极端案例admitted by Microsoft是非标准行为。有谁知道为什么MSVC ++有这个特定的限制?
它涉及同时使用三种语言特征(“虚拟基类”,“协变返回类型”和“可变数量的参数”,根据第二个链接页面中的描述)在语义上正交和单独完全支持似乎暗示这不是解析或语义问题,而是Microsoft C ++ ABI中的一个极端情况。特别是,涉及“可变数量的参数”的事实似乎(?)表明C ++ ABI使用隐式尾随参数来实现其他两个特征的组合,但不能因为没有固定的位置在函数为var arg时放置该参数。
有没有人对Microsoft C ++ ABI有足够的了解以确认是否是这种情况,并解释这个隐含的尾随参数用于什么(或者如果我的猜测不正确,还会发生什么)?微软没有记录C ++ ABI,但我知道微软以外的一些人因各种原因做了匹配ABI的工作,所以我希望有人可以解释发生了什么。
此外,微软的文档有点不一致;链接的第二页说:
当虚函数具有可变数量的参数时,不支持虚拟基类作为协变返回类型。
但第一页更广泛地说明了:
协变返回,varargs函数不支持多个虚拟继承
有谁知道真实的故事是什么?我可以做一些实验来找出答案,但我猜测实际的角落案例既不是这些,也不是完全相同的,而是与文档管理员决定掩饰的方式有关。我猜它与虚拟thunk中指针调整的需要有关,但我希望有更深入了解情况的人比我能解释幕后发生的事情。
答案 0 :(得分:2)
我可以告诉你,MSVC的C ++ ABI使用隐式额外参数来执行其他ABI(即Itanium)实现多个单独函数来处理的事情,因此不难想象在这里使用一个(或者会如果案件得到支持的话。)
我不确定在这种情况下发生了什么,但似乎有理由传递隐式额外参数来告诉实现虚函数的thunk是否需要向协变返回类型类的向下转换(或者,更有可能的是,是否需要向上返回基类,因为实际的实现函数可能返回派生类),并且这个额外的参数是最后的,所以它可以被基类忽略(它不会知道任何东西)关于协变回归)。
这意味着当虚拟基类是原始返回类型时(因为对于派生类总是需要thunk),总是会出现不支持的边角情况,这是第一个引用中描述的内容;它也会发生在涉及多重继承的一些但不是全部的情况下(这可能就是为什么它包含在第二个引用中,但不包括在第一个引用中)。