gpt4 book ai didi

指向成员的指针的 C++ 类内初始化使 MSVC 失败(但 GCC/Clang 工作)

转载 作者:可可西里 更新时间:2023-11-01 17:59:52 25 4
gpt4 key购买 nike

这是一个非常简单的 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.似乎是个bug)

编辑 - 我发现 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(类) 具有虚拟成员函数。

关于指向成员的指针的 C++ 类内初始化使 MSVC 失败(但 GCC/Clang 工作),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57157627/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com