簡體   English   中英

成員指針的C ++類內初始化使MSVC失敗(但GCC / Clang起作用)

[英]C++ in-class initialization of pointer-to-member makes MSVC to fail (but GCC/Clang work)

這是一個非常簡單的C ++代碼:

#include <iostream>

struct A
{
    int a;
    constexpr static int A::* p = &A::a;
    virtual void f() {}
};
int main()
{
    A x; x.a = 0;
    x.*(A::p) = 1234;
    std::cout << x.a;
}

更令人震驚的是,這段代碼在GCC,Clang和MSVC之間顯示了不同的結果。

我已經嘗試了4個編譯器

  1. GCC:編譯良好,打印1234

  2. Clang:編譯良好,輸出1234

  3. MSVC(在線):無法編譯。

  4. Visual Studio 2019的MSVC(本地):編譯良好,打印0 (有趣的是,如果我刪除f()它將顯示1234

我不確定使用其自己的成員進行的指向成員的指針的類內初始化是否合法,但我認為此代碼應該打印1234

Compiler ExplorerRextester上試用

我不知道誰是對的。 (至少4.似乎是一個錯誤)

編輯-我發現3.和4.的區別來自編譯器選項/permissive 但是/permissive和no- /permissive仍然與gcc和clang不同。

更新資料

這是經過稍微修改的代碼,似乎在Visual Studio 2019中按預期工作:

struct A
{
    int a;
    constexpr static int A::* p() { return &A::a; }
    virtual void f() {}
};

using namespace std;
int main()
{
    A x;
    void* px = &x;
    x.a = 0;
    x.*(A::p()) = 1234;
    cout << x.a << endl;

    getchar();
}

更新結束


剛剛在Visual Studio 2019上嘗試過,我將代碼修改為此:

#include <iostream>

struct A
{
    int a;
    constexpr static int A::* p = &A::a;
    virtual void f() {}
};

struct B
{
    int a;
    constexpr static int B::* p = &B::a;
};

using namespace std;

void printBytes(void* p, size_t length = 16) {
    uint8_t* pu = (uint8_t*)p;
    cout << "  ";
    for (size_t i = 0; i < length; ++i) {
        auto val = *(pu + i);
        printf("%02x ", val);
    }
    cout << endl;
}

int main()
{
    A x;
    void* px = &x;
    cout << "\nfor A:\n";
    printBytes(px);
    x.a = 0;
    printBytes(px);
    x.*(A::p) = 0x1234;
    printBytes(px);
    cout << x.a << endl;

    B y;
    void* py = &y;
    cout << "\nfor B:\n";
    printBytes(py);
    y.a = 0;
    printBytes(py);
    y.*(B::p) = 0x1234;
    printBytes(py);
    cout << y.a << endl;

    getchar();
}

輸出為:


for A:
  fc 9c 2c 01 cc cc cc cc cc cc cc cc 0f 40 04 09
  fc 9c 2c 01 00 00 00 00 cc cc cc cc 0f 40 04 09
  34 12 00 00 00 00 00 00 cc cc cc cc 0f 40 04 09
0

for B:
  cc cc cc cc cc cc cc cc cc cc cc cc 60 fd 3d 01
  00 00 00 00 cc cc cc cc cc cc cc cc 60 fd 3d 01
  34 12 00 00 cc cc cc cc cc cc cc cc 60 fd 3d 01
4660

B案例按預期工作,但是對於A案例 ,上面的輸出表明此行:

x.*(A::p) = 0x1234;

0x1234寫入“指向虛擬功能表的指針”所在的位置。

因此,我想Visual Studio 2019的編譯器在具有虛擬成員函數的struct(class )上的表達式&A::a (也獲得指向成員變量的指針)上犯了一個錯誤

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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