[英]Virtual tables on anonymous classes
我的代碼中有類似的東西:
#include <iostream>
#include <cstdlib>
struct Base
{
virtual int Virtual() = 0;
};
struct Child
{
struct : public Base
{
virtual int Virtual() { return 1; }
} First;
struct : public Base
{
virtual int Virtual() { return 2; }
} Second;
};
int main()
{
Child child;
printf("ble: %i\n", ((Base*)&child.First)->Virtual());
printf("ble: %i\n", ((Base*)&child.Second)->Virtual());
system("PAUSE");
return 0;
}
我希望這會給出這個輸出:
ble: 1
ble: 2
當它在GCC下編譯時(3.4.5我相信)。
但是,在Visual Studio 2008下編譯並運行它,可以得到:
ble: 2
ble: 2
有趣的是,如果我給出了Base派生的結構名稱( struct s1 : public Base
),它就能正常工作。
哪種行為(如果有的話)是正確的? VS只是嬌小,還是堅持標准? 我錯過了一些重要的東西嗎?
看起來這是VS 2008中的一個錯誤,可能是因為它覆蓋或忽略了第一個未命名的類的vtable而支持第二個vtable,因為內部名稱是相同的。 (當您明確命名一個時,vtable的內部名稱不再相同。)
據我所知,從標准來看,這應該像你期望的那樣工作,而gcc是正確的。
可以看出MSVC如何從調試符號中弄錯。 它為匿名結構生成臨時名稱,分別為Child::<unnamed-type-First>
和Child::<unnamed-type-Second>
。 但是只有一個vtable,它名為Child::<unnamed-tag>::'vftable'
,兩個構造Child::<unnamed-tag>::'vftable'
都使用它。 vtable的不同名稱肯定是bug的一部分。
connection.microsoft.com上報告了幾個與匿名類型相關的錯誤,這些錯誤都沒有使其成為“必須修復”狀態。 不是你找到的那個,但是。 也許解決方法太簡單了。
我可以確認這是VC編譯器中的一個已知錯誤(它在VC10中存儲); 兩個匿名類錯誤地共享vtable。
匿名結構不是 C ++標准的一部分。
編輯 :匿名結構是一種含糊不清的術語。 它可能意味着兩件事:
class outer
{
public:
struct {
int a;
int b;
} m_a; // 1
struct {
int c;
}; // 2
union {
int d;
int e;
}; // 3
};
1是這里發生的事情,一個比匿名結構更好的名稱將是“未命名的結構”。 結構類型本身沒有名稱,但對象有(m_a)。
2也稱為匿名結構,並不是合法的C ++。 沒有對象名稱,您可以直接在外部類型的對象上訪問字段“c”。 這只是因為Visual Studio中的編譯器擴展而編譯(在/ Za下會失敗)
相比之下,匿名工會是合法的C ++。
我把這兩個混淆了,因為在這里我們稱#1為“匿名結構”,而我腦中的電線與#2交叉。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.