2013-08-31 44 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總是要求派生類),這是第一個引用中描述的;它也會發生在涉及多重繼承的一些但不是全部的情況下(這可能是爲什麼它包含在第二個引用中,但不是第一個引用)。