提问人:rashi 提问时间:10/26/2022 最后编辑:Spencerrashi 更新时间:10/27/2022 访问量:82
从 int 到 class 的类型转换行为异常
type conversion from int to class behaving weirdly
问:
所以。我正在尝试将uint16_t(16 字节 int)转换为类。获取类成员 varaible。但它没有按预期工作。
class test{
public:
uint8_t m_pcp : 3; // Defining max size as 3 bytes
bool m_dei : 1;
uint16_t m_vid : 12; // Defining max size as 12 bytes
public:
test(uint16_t vid, uint8_t pcp=0, bool dei=0) {
m_vid = vid;
m_pcp = pcp;
m_dei = dei;
}
};
int main() {
uint16_t tci = 65535;
test t = (test)tci;
cout<<"pcp: "<<t.m_pcp<<" dei: "<<t.m_dei<<" vid "<<t.m_vid<<"\n";
return 0;
}
预期输出:
pcp:1 dei: 1 vid 4095
实际输出:
pcp: dei: 0 vid 4095
也
cout<<sizeof(t)
返回 2。不应该是4吗?
我做错了什么吗?
答:
-1赞
Scott Settlemier
10/26/2022
#1
位字段总共有 16 位,因此 2 个字节的大小是正确的。(编译器会将相邻的位字段打包在一起 - 但要小心,因为可能因编译器而异)单个 uint16_t 值的构造函数仅将值的 12 位分配给 m_vid,将 0 分配给其他成员。65535 的前 12 位是 4095,因此输出是正确的,正如您所注意的那样(注意:您对位字段是字节的注释应为“位”),但您对其他位的期望是偏离的。构造函数明确表示,如果未指定,则为它们提供 0 值。
1赞
Nelfeal
10/26/2022
#2
test t = (test)tci;
此行不会执行您期望的强制转换(这将是 ,但它不会编译)。它只是使用默认值调用构造函数。因此被分配截断为 12 位,并且被分配 。尝试删除构造函数以查看它是否未编译。reinterpret_cast
m_vid
65535
m_pcp
m_dei
0
我知道做你想做的事的唯一方法是编写一个正确的构造函数,如下所示:
test(uint16_t i) {
m_vid = i & 0x0fff;
i >>= 12;
m_dei = i & 0x1;
i >>= 1;
m_pcp = i & 0x7;
}
另外,我不确定为什么你会期望是 1,因为 65535 的 3 位最高位等于 7。m_pcp
此外,返回 2。不应该是4吗?
cout<<sizeof(t)
不,3+1+12=16 位等于 2 个字节。
评论
4
tci
test