下面是一个非常简单的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
。
叮当声:编译良好,打印1234
。
MSVC(在线):编译失败。
带有Visual Studio 2019的MSVC(本地):编译良好,打印0
。(有趣的是,如果我删除f()
,它会打印1234
。)
我不确定指向成员的指针及其自己的成员的类内初始化是否合法,但我相信这段代码应该打印1234
。
在编译器资源管理器或Rextester上试用。
我不知道谁是对的。(至少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 事例,上面的输出表明以下行:
< code > x . *(A::p)= 0x 1234;
将< code>0x1234写入“指向虚函数表的指针”所在的位置。
所以,我认为Visual Studio 2019的编译器在表达式< code >上犯了一个错误
在C++98标准里,只有static const声明的整型成员能在类内部初始化,并且初始化值必须是常量表达式。这些限制确保了初始化操作可以在编译时期进行。例如: int var = 7; class X { static const int m1 = 7; // 正确 const int m2 = 7; // 错误:无static static int m3 =
请查看以下代码: gcc和clang编译并链接它时没有任何问题,而MSVC(2015、2019)生成了未解决的外部符号“void _cdecl test(int*)” 请注意,如果从库中删除const关键字。cpp然后MSVC链接代码。 谁在这里?是MSVC的错误吗?
问题内容: 我最近刚与Python中的一个错误作斗争。那是那些愚蠢的新手错误之一,但是它让我思考了Python的机制(我是C ++的老程序员,是Python的新手)。我将列出错误的代码并解释如何解决该问题,然后我有两个问题。 场景:我有一个叫做A的类,它有一个字典数据成员,下面是其代码(当然这是简化的): 使用此代码的类为B类: 请注意,每次调用都会初始化类A的新“干净”实例,并在添加前后打印字典
我正在尝试同时处理MSVC和GCC编译器,同时更新这个代码库以在GCC上工作。但我不确定GCCs内联ASM是如何工作的。现在我并不擅长将ASM转换为C,否则我就会使用C而不是ASM。 我假设ROR13的工作方式类似于,但代码不会产生相同的输出。 什么是将这个内联ASM翻译成GCC的正确方法,或者这个代码的C翻译是什么?
这个问题的后续问题 我们有以下代码: 这种访问是一种未定义的行为吗?一方面,不需要对象来访问静态类成员,另一方面,
对于中继中的工作正常,但对于来自中继的,失败并显示错误消息(链接): 错误:未为此 lambda 函数捕获“此” 在命名空间范围内定义对两者都适用。 使用 lambda 捕获稍微修改的定义也适用于全局或本地范围。 哪个编译器是对的?