簡體   English   中英

匿名類的虛擬表

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM