我有以下片段

#include <iostream>

using namespace std;

class foobar
{
    public:
    unsigned int a = 97;
    unsigned int b = 98;
    unsigned int c = 99;
};


class barfoo
{
    public:
    char a:32,b:32,c;

};


int main(){
    foobar * f = new foobar();
    barfoo * b = (reinterpret_cast<barfoo *>(f));
    cout << b->a << "-" << b->b << "-" << b->c;

}


输出:

a-b-c


但是,如果我在barfoo中指定c的宽度,则它将不起作用(所有值均为0)。观察

#include <iostream>

using namespace std;

class foobar
{
    public:
    unsigned int a = 97;
    unsigned int b = 98;
    unsigned int c = 99;
};


class barfoo
{
    public:
    char a:32,b:32,c:32;

};


int main(){
    foobar * f = new foobar();
    barfoo * b = (reinterpret_cast<barfoo *>(f));
    cout << b->a << "-" << b->b << "-" << b->c;

}


输出:

--


字符全为0

知道为什么会这样吗?

链接到ideone first snippet-工作

链接到ideone second snippet-不起作用

编译器是gcc-5.1
谢谢!!

最佳答案

首先,检查两个类的大小是否相同。可以想象,填充和对齐可能会使位域a,b和c的位置与正常成员a,b和c等的位置不同。为什么将char用于32位位域?我的编译器警告位域超过类型的大小。

否则(如果将barfoo类的char更改为unsigned int),无论您遇到任何标准的UB,reinterpret_cast和access都有很大的工作机会。如果您使用通过联合进行类型处理的良好支持和完善的习惯用法,则可能更是如此。

通过联合进行类型处理是一种告诉编译器“这两种不同类型的指针可能会别名的方法,请假设它们可能不会别名,请不要进行根本性的优化”。

关于c++ - C++:reinterpret_cast的异常行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38349388/

10-11 04:15