[英]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個編譯器
GCC:編譯良好,打印1234
。
Clang:編譯良好,輸出1234
。
MSVC(在線):無法編譯。
Visual Studio 2019的MSVC(本地):編譯良好,打印0
。 (有趣的是,如果我刪除f()
它將顯示1234
)
我不確定使用其自己的成員進行的指向成員的指針的類內初始化是否合法,但我認為此代碼應該打印1234
。
在Compiler Explorer或Rextester上試用 。
我不知道誰是對的。 (至少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.