c++20 std::reinterpret_cast、std::bit_cast、std::static_cast

std::reinterpret_cast 类型不相关的转换,不安全例如转为&,不支持,要求sizeof相同

uint32_t n32 = 12345678;//0x00bc614e
uint32_t* ptr = reinterpret_cast<uint32_t*>(n32);//0x00bc614e
uint32_t& ref = reinterpret_cast<uint32_t&>(n32);//0x00bc614e 危险操作
uint32_t n32a = *reinterpret_cast<uint32_t*>(n32);//崩溃,非法内存访问
uint16_t n16 = reinterpret_cast<uint16_t>(n32);;//编译错误error C2440: “reinterpret_cast”: 无法从“uint32_t”转换为“uint16_t”
float f = reinterpret_cast<float>(n);//error C2440: “reinterpret_cast”: 无法从“uint32_t”转换为“float”
}

std::bit_cast 将源对象的位解释为目标对象位,不可转为&,要求sizeof相同无损的转换,用于可复制类型的二进制IO,例如将字节写入文件,再读回内存。

bool b = is_trivially_copyable_v<int&>;//false
float f = 3.14f;//0x4048f5c3
uint32_t n32 = std::bit_cast<uint32_t>(f);//0x4048f5c3
uint32_t n32ref = std::bit_cast<uint32_t&>(f);//编译不通过error C2672: “std::bit_cast”: 未找到匹配的重载函数//is_trivially_copyable_v<int&>;//false
uint16_t n16 = std::bit_cast<uint16_t>(f);//编译不通过error C2672: “std::bit_cast”: 未找到匹配的重载函数//bool_constant<sizeof(_To) == sizeof(_From)>

//uint32_t无损转为float
//实现1
uint32_t Value = 0x12345678;
float Tr_Data = *((float*)(&Value));//0x12345678
//实现2
float f = std::bit_cast<float>(0x12345678);//0x12345678

std::static_cast随意转换,可能是有损的转换,级别较低,不出现编译错误,问题不容易被发现。

float f = 33333333.14f;//0x4bfe502b
uint32_t i = static_cast<uint32_t>(f);//0x01fca056
uint32_t n32 = (uint32_t)f;//0x01fca056
uint16_t n16 = (uint16_t)f;//0x0000a056
//static_cast想怎么转都能转成功,可能是有损的转换

reinterpret_cast不能在constexpr中使用,std::bit_cast可以。reinterpret_cast是语言功能,std::bit_cast是库函数,库函数比语言功能容易支持。

inline std::string expand(const std::string &origin_value, int64_t length) { std::string src = origin_value; std::string ans; if (src.empty()) { for (int i = 0; i < length; ++i) { ans += 'A'; } return ans; } else if (src.size() >= length) { for (int i = 0; i < length; ++i) { ans += src[i]; } return ans; } for (int i = 0; i < length / src.size(); ++i) { ans += src; } for (int i = 0; i < length % src.size(); ++i) { ans += src[i]; } return ans; }这是expand函数,我的调用方式有什么问题#include "StringLengthEdgeCase.h" #include <algorithm> #include "../utils.h" StringLengthEdgeCase::StringLengthEdgeCase(std::shared_ptr<StringBase> obj, std::mt19937 rand) : IntegerEdgeCases(obj, rand) { } std::pair<int64_t, int64_t> StringLengthEdgeCase::get_limits(std::shared_ptr<StringBase> obj) { int64_t max_ = obj->mutator_config.max_output_size * 8; int64_t size = obj->calculate_bit_size(); int64_t limit = std::max(max_, size); limit = (limit + 7) / 8; max_ = limit; if (obj->max_length >= 0) { max_ = std::min(max_, obj->max_length); } int64_t min_ = 0; if (obj->min_length >= 0) { min_ = std::max(min_, obj->min_length); } return std::make_pair(min_, max_); } bool StringLengthEdgeCase::supported(std::shared_ptr<StringBase> obj) { auto ptr = std::dynamic_pointer_cast<String>(obj); return (ptr != nullptr); } void StringLengthEdgeCase::perform_mutation(std::shared_ptr<StringBase> obj, int64_t value) { std::vector<uint8_t> origin_value(obj->value.begin(), obj->value.end()); std::vector<uint8_t> expanded = expand(origin_value, static_cast<size_t>(value)); std::string mutated_str(expanded.begin(), expanded.end()); obj->mutated_value = mutated_str; obj->mutated = true; }
07-01
请仔细阅读和分析下面函数,进行优化后,采用C/C++11标准,完整推导并重构可编译的全部代码 要求如下: 1.保持所有原始功能不变,不要遗漏逻辑细节 2.提高执行效率,降低计算复杂度 3.已经给定的结构体名字和元素不要更改,详细的中文注释 4.自动添加中文注释说明功能逻辑 5.不使用 auto,使用显式 for 循环 6.结构体采用32位定义 7.不要使用小函数,保持原始的函数定义 8.严格保持protobuf字段映射关系 特别注意: 1.函数中有关位操作不变,函数间的位操作一致 2.函数中的 HDDMXng::BelUsageAttrib::BelUsageAttrib 映射为 message BelUsageAttrib { optional uint32 flags = 1; optional uint32 type = 2; optional uint32 bitwidth = 3; optional string attribname = 4; optional sint32 defint = 5; optional double defdouble = 6; optional bool defbool = 7; optional string defstring = 8; repeated sint32 listofints = 9 [packed = true]; repeated double listofdoubles = 10 [packed = true]; repeated bool listofbools = 11 [packed = true]; repeated string listofstrings = 12; optional uint32 precision = 13; } 3.采用 google::protobuf::Descriptor 和 google::protobuf::Reflection 进行编程 将函数中的 _BYTE attrib_msg[8] 映射为 HDDMXng::BelUsageAttrib attrib_msg void __cdecl HDDMBelUsageAttrib::readme_pb(HDDMBelUsageAttrib *this, std::istream *a2) { char v2; // al google::protobuf::Message *n; // [esp+8h] [ebp-174h] _BYTE attrib_msg[8]; // [esp+A0h] [ebp-DCh] BYREF unsigned int v5; // [esp+A8h] [ebp-D4h] char v6; // [esp+ACh] [ebp-D0h] std::string *v7; // [esp+B0h] [ebp-CCh] int v8; // [esp+B4h] [ebp-C8h] __int16 v9; // [esp+11Ch] [ebp-60h] char v10; // [esp+158h] [ebp-24h] char v11; // [esp+159h] [ebp-23h] if ( HDDMDeviceDump::useXngMarks ) std::istream::read(a2, HDDMDeviceDump::markBuffer, 14); HDDMXng::BelUsageAttrib::BelUsageAttrib((HDDMXng::BelUsageAttrib *)attrib_msg); HDDMDevice::readMessage(a2, (std::istream *)attrib_msg, n); v2 = (((v5 & 0x10) != 0) << 6) | (4 * ((v5 & 8) != 0)) | (2 * ((v5 & 4) != 0)) & 0xBB | ((v5 & 2) != 0) | HIBYTE(this->attrib_flags) & 0xB8; BYTE1(this->attrib_type) = ((unsigned __int8)(v5 >> 7) << 7) | (((v5 & 0x40) != 0) << 6) & 0x7F | (32 * ((v5 & 0x20) != 0)) & 0x7F | BYTE1(this->attrib_type) & 0x1F; HIBYTE(this->attrib_flags) = (8 * (v6 & 7)) | v2 & 0xC7; if ( (v10 & 4) != 0 ) LOWORD(this->attrib_flags) = v8 & 0xFFF | this->attrib_flags & 0xF000; std::string::assign((std::string *)&this->hddmbelusageattrib8, v7); if ( ((HIBYTE(this->attrib_flags) >> 3) & 7) != 7 ) __asm { jmp eax } if ( (v11 & 0x10) != 0 ) BYTE1(this->attrib_type) = (4 * (v9 & 7)) | BYTE1(this->attrib_type) & 0xE3 | 2; HDDMXng::BelUsageAttrib::~BelUsageAttrib((HDDMXng::BelUsageAttrib *)attrib_msg); } 将函数中的 _BYTE attrib_msg[8] 映射为 HDDMXng::BelUsageAttrib attrib_msg void __cdecl HDDMBelUsageAttrib::writeme_pb(HDDMBelUsageAttrib *this, std::ostream *stream) { unsigned __int8 attrib_flags_high; // cl int v3; // eax char v4; // dl int v5; // eax unsigned __int16 v6; // cx std::string *p__ZN6google8protobuf8internal12kEmptyStringE_1; // eax const google::protobuf::Message *n; // [esp+8h] [ebp-104h] _BYTE attrib_msg[8]; // [esp+30h] [ebp-DCh] BYREF int v10; // [esp+38h] [ebp-D4h] int v11; // [esp+3Ch] [ebp-D0h] std::string *p__ZN6google8protobuf8internal12kEmptyStringE; // [esp+40h] [ebp-CCh] int v13; // [esp+44h] [ebp-C8h] int v14; // [esp+E8h] [ebp-24h] if ( HDDMDeviceDump::useXngMarks ) std::ostream::write(stream, "BELUSAGEATTRIB", 14); HDDMXng::BelUsageAttrib::BelUsageAttrib((HDDMXng::BelUsageAttrib *)attrib_msg); attrib_flags_high = HIBYTE(this->attrib_flags); v3 = (attrib_flags_high & 1) == 0 ? 4 : 6; if ( (attrib_flags_high & 2) == 0 ) v3 = (this->attrib_flags & 0x1000000) != 0 ? 2 : 0; if ( (attrib_flags_high & 4) != 0 ) v3 |= 8u; if ( (attrib_flags_high & 0x40) != 0 ) v3 |= 0x10u; v4 = BYTE1(this->attrib_type); if ( (v4 & 0x20) != 0 ) v3 |= 0x20u; if ( (v4 & 0x40) != 0 ) v3 |= 0x40u; if ( v4 < 0 ) v3 |= 0x80u; v10 = v3; v11 = (attrib_flags_high >> 3) & 7; v5 = v14 | 3; v6 = this->attrib_flags & 0xFFF; if ( v6 ) { v13 = v6; v5 = v14 | 7; } v14 = v5 | 8; p__ZN6google8protobuf8internal12kEmptyStringE_1 = p__ZN6google8protobuf8internal12kEmptyStringE; if ( p__ZN6google8protobuf8internal12kEmptyStringE == (std::string *)&google::protobuf::internal::kEmptyString ) { p__ZN6google8protobuf8internal12kEmptyStringE_1 = (std::string *)operator new(4u); *(_DWORD *)p__ZN6google8protobuf8internal12kEmptyStringE_1 = (char *)&std::string::_Rep::_S_empty_rep_storage + 12; p__ZN6google8protobuf8internal12kEmptyStringE = p__ZN6google8protobuf8internal12kEmptyStringE_1; } std::string::assign(p__ZN6google8protobuf8internal12kEmptyStringE_1, (const std::string *)&this->hddmbelusageattrib8); if ( ((HIBYTE(this->attrib_flags) >> 3) & 7) != 7 ) __asm { jmp eax } HDDMDevice::writeMessage(stream, (std::ostream *)attrib_msg, n); HDDMXng::BelUsageAttrib::~BelUsageAttrib((HDDMXng::BelUsageAttrib *)attrib_msg); } int __cdecl HDDMBelUsageAttrib::print(HDDMBelUsageAttrib *this) { char n3; // al _DWORD *v2; // eax _DWORD *j_1; // edi _DWORD *j; // eax int result; // eax _DWORD *v6; // eax _DWORD *i_1; // edi _DWORD *i; // eax int v9; // edi int v10; // eax int n31_1; // edx _DWORD *k_1; // ecx int v13; // eax int v14; // ecx int v15; // edi int v16; // eax int v17; // edi _DWORD *v18; // eax _DWORD *m_1; // edi _DWORD *m; // eax _DWORD *v21; // edi _DWORD *k; // [esp+18h] [ebp-34h] __int64 v23; // [esp+18h] [ebp-34h] int n31; // [esp+20h] [ebp-2Ch] _DWORD *k_2; // [esp+24h] [ebp-28h] n3 = (HIBYTE(this->attrib_flags) >> 3) & 7; if ( n3 != 2 ) { if ( n3 != 3 ) { if ( n3 == 1 ) { std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "int ", 4); std::__ostream_insert<char,std::char_traits<char>>( &std::cout, this->hddmbelusageattrib8, *(_DWORD *)(this->hddmbelusageattrib8 - 12)); std::__ostream_insert<char,std::char_traits<char>>(&std::cout, " ( ", 3); v6 = (_DWORD *)*((_DWORD *)this + 3); if ( v6 ) { i_1 = (_DWORD *)*v6; for ( i = (_DWORD *)v6[1]; i_1 != i; i = i_1 ) { while ( 1 ) { std::ostream::operator<<(&std::cout, *i_1++); if ( *(_DWORD **)(*((_DWORD *)this + 3) + 4) == i_1 ) break; std::__ostream_insert<char,std::char_traits<char>>(&std::cout, ", ", 2); if ( i_1 == *(_DWORD **)(*((_DWORD *)this + 3) + 4) ) goto LABEL_19; } } } LABEL_19: if ( (this->attrib_flags & 0x1000000) != 0 ) { v9 = *((_DWORD *)this + 4); std::__ostream_insert<char,std::char_traits<char>>(&std::cout, " default=", 9); std::ostream::operator<<(&std::cout, v9); } } else { std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "string ", 7); std::__ostream_insert<char,std::char_traits<char>>( &std::cout, this->hddmbelusageattrib8, *(_DWORD *)(this->hddmbelusageattrib8 - 12)); std::__ostream_insert<char,std::char_traits<char>>(&std::cout, " ( ", 3); v2 = (_DWORD *)*((_DWORD *)this + 3); if ( v2 ) { j_1 = (_DWORD *)*v2; for ( j = (_DWORD *)v2[1]; j_1 != j; j = j_1 ) { while ( 1 ) { std::__ostream_insert<char,std::char_traits<char>>(&std::cout, *j_1, *(_DWORD *)(*j_1 - 12)); if ( *(_DWORD **)(*((_DWORD *)this + 3) + 4) == ++j_1 ) break; std::__ostream_insert<char,std::char_traits<char>>(&std::cout, ", ", 2); if ( j_1 == *(_DWORD **)(*((_DWORD *)this + 3) + 4) ) goto LABEL_9; } } } LABEL_9: if ( (this->attrib_flags & 0x1000000) != 0 ) { v21 = (_DWORD *)*((_DWORD *)this + 4); std::__ostream_insert<char,std::char_traits<char>>(&std::cout, " default=", 9); std::__ostream_insert<char,std::char_traits<char>>(&std::cout, *v21, *(_DWORD *)(*v21 - 12)); } } goto LABEL_11; } std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "bool ", 5); std::__ostream_insert<char,std::char_traits<char>>( &std::cout, this->hddmbelusageattrib8, *(_DWORD *)(this->hddmbelusageattrib8 - 12)); std::__ostream_insert<char,std::char_traits<char>>(&std::cout, " ( ", 3); v10 = *((_DWORD *)this + 3); if ( !v10 ) { LABEL_34: if ( (this->attrib_flags & 0x1000000) != 0 ) { v17 = *((unsigned __int8 *)this + 16); std::__ostream_insert<char,std::char_traits<char>>(&std::cout, " default=", 9); std::ostream::_M_insert<bool>(&std::cout, v17); } goto LABEL_11; } n31 = *(_DWORD *)(v10 + 4); n31_1 = *(_DWORD *)(v10 + 12); k_1 = *(_DWORD **)(v10 + 8); for ( k = *(_DWORD **)v10; ; ++k ) { if ( k_1 == k ) { LABEL_33: if ( n31 == n31_1 ) goto LABEL_34; } while ( 1 ) { std::ostream::_M_insert<bool>(&std::cout, ((1 << n31) & *k) != 0); v13 = *((_DWORD *)this + 3); k_2 = *(_DWORD **)(v13 + 8); v14 = n31 + 32; v15 = n31 + 1; if ( n31 + 1 >= 0 ) v14 = n31 + 1; k_1 = (_DWORD *)((char *)k + ((v14 >> 3) & 0xFFFFFFFC)); n31_1 = v15 % 32; if ( v15 % 32 < 0 ) { n31_1 += 32; if ( --k_1 != k_2 ) goto LABEL_30; } else if ( k_1 != k_2 ) { goto LABEL_30; } if ( n31_1 != *(_DWORD *)(v13 + 12) ) { LABEL_30: std::__ostream_insert<char,std::char_traits<char>>(&std::cout, ", ", 2); v16 = *((_DWORD *)this + 3); n31_1 = *(_DWORD *)(v16 + 12); k_1 = *(_DWORD **)(v16 + 8); } if ( n31 == 31 ) break; ++n31; if ( k_1 == k ) goto LABEL_33; } n31 = 0; } } std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "double ", 7); std::__ostream_insert<char,std::char_traits<char>>( &std::cout, this->hddmbelusageattrib8, *(_DWORD *)(this->hddmbelusageattrib8 - 12)); std::__ostream_insert<char,std::char_traits<char>>(&std::cout, " ( ", 3); v18 = (_DWORD *)*((_DWORD *)this + 3); if ( v18 ) { m_1 = (_DWORD *)*v18; for ( m = (_DWORD *)v18[1]; m_1 != m; m = m_1 ) { while ( 1 ) { std::ostream::_M_insert<double>(&std::cout, *m_1, m_1[1]); m_1 += 2; if ( *(_DWORD **)(*((_DWORD *)this + 3) + 4) == m_1 ) break; std::__ostream_insert<char,std::char_traits<char>>(&std::cout, ", ", 2); if ( m_1 == *(_DWORD **)(*((_DWORD *)this + 3) + 4) ) goto LABEL_45; } } } LABEL_45: if ( (this->attrib_flags & 0x1000000) != 0 ) { v23 = *((_QWORD *)this + 2); std::__ostream_insert<char,std::char_traits<char>>(&std::cout, " default=", 9); std::ostream::_M_insert<double>(&std::cout, v23, HIDWORD(v23)); } LABEL_11: result = std::__ostream_insert<char,std::char_traits<char>>(&std::cout, " ) ", 3); if ( (this->attrib_flags & 0x2000000) != 0 ) return std::__ostream_insert<char,std::char_traits<char>>(&std::cout, " (HIDDEN=true)", 14); return result; } void __cdecl HDDMBelUsageAttrib::HDDMBelUsageAttrib(HDDMBelUsageAttrib *this) { LOWORD(this->attrib_flags) &= 0xF000u; this->attrib_flags |= 0xFFF000u; HIBYTE(this->attrib_flags) = 0; LOWORD(this->attrib_type) &= 0xFE00u; BYTE1(this->attrib_type) &= 1u; BYTE2(this->attrib_type) &= 0xF0u; HIWORD(this->attrib_type) |= 0xFFF0u; this->hddmbelusageattrib8 = (int)&std::string::_Rep::_S_empty_rep_storage + 12; *((_DWORD *)this + 7) = 0; *((_DWORD *)this + 8) = 0; *((_DWORD *)this + 11) = 0; *((_DWORD *)this + 9) = (char *)this + 28; *((_DWORD *)this + 10) = (char *)this + 28; *((_QWORD *)this + 2) = 0; *((_DWORD *)this + 3) = 0; } void __cdecl HDDMBelUsageAttrib::~HDDMBelUsageAttrib(HDDMBelUsageAttrib *this) { HDDMBelUsageAttrib *this_1; // esi char n2; // al void **v3; // eax _DWORD *v4; // ecx int *v5; // edi void *p__ZNSs4_Rep20_S_empty_rep_storageE; // edx void *v7; // eax _DWORD *attrib_type; // edi void **v9; // edi int hddmbelusageattrib8; // eax int v11; // edx int v12; // eax int v13; // eax void *p__ZNSs4_Rep20_S_empty_rep_storageE_1; // ecx int v15; // ecx int v16; // edx void **v17; // [esp+14h] [ebp-38h] _DWORD *v18; // [esp+1Ch] [ebp-30h] int *v19; // [esp+1Ch] [ebp-30h] _BYTE v20[29]; // [esp+2Fh] [ebp-1Dh] BYREF this_1 = this; n2 = (HIBYTE(this->attrib_flags) >> 3) & 7; if ( n2 == 2 || n2 == 3 || n2 == 1 ) { v9 = (void **)*((_DWORD *)this + 3); if ( v9 ) { if ( *v9 ) operator delete(*v9); operator delete(v9); } *((_DWORD *)this + 3) = 0; } else { v3 = (void **)*((_DWORD *)this + 3); v17 = v3; if ( v3 ) { v4 = v3[1]; v5 = (int *)*v3; if ( v4 == *v3 ) { v7 = v3[1]; } else { if ( &_pthread_key_create ) { do { p__ZNSs4_Rep20_S_empty_rep_storageE = (void *)(*v5 - 12); if ( p__ZNSs4_Rep20_S_empty_rep_storageE != &std::string::_Rep::_S_empty_rep_storage && _InterlockedExchangeAdd((volatile signed __int32 *)(*v5 - 4), 0xFFFFFFFF) <= 0 ) { v18 = v4; std::string::_Rep::_M_destroy(p__ZNSs4_Rep20_S_empty_rep_storageE, v20); v4 = v18; } ++v5; } while ( v4 != v5 ); } else { v19 = (int *)v3[1]; do { v13 = *v5; p__ZNSs4_Rep20_S_empty_rep_storageE_1 = (void *)(*v5 - 12); if ( p__ZNSs4_Rep20_S_empty_rep_storageE_1 != &std::string::_Rep::_S_empty_rep_storage ) { v16 = *(_DWORD *)(v13 - 4); *(_DWORD *)(v13 - 4) = v16 - 1; if ( v16 <= 0 ) std::string::_Rep::_M_destroy(p__ZNSs4_Rep20_S_empty_rep_storageE_1, v20); } ++v5; } while ( v19 != v5 ); } this_1 = this; v7 = *v17; } if ( v7 ) operator delete(v7); operator delete(v17); this_1[1].attrib_flags = 0; } attrib_type = (_DWORD *)this_1[1].attrib_type; if ( attrib_type ) { std::string::_Rep::_M_dispose(*attrib_type - 12); operator delete(attrib_type); this_1[1].attrib_type = 0; } } std::_Rb_tree<HSTString,std::pair<HSTString const,unsigned short>,std::_Select1st<std::pair<HSTString const,unsigned short>>,std::less<HSTString>,std::allocator<std::pair<HSTString const,unsigned short>>>::_M_erase( (int)&this_1[2], (void *)this_1[2].hddmbelusageattrib8); hddmbelusageattrib8 = this_1->hddmbelusageattrib8; v11 = hddmbelusageattrib8 - 12; if ( (_UNKNOWN *)(hddmbelusageattrib8 - 12) != &std::string::_Rep::_S_empty_rep_storage ) { if ( &_pthread_key_create ) { v12 = _InterlockedExchangeAdd((volatile signed __int32 *)(hddmbelusageattrib8 - 4), 0xFFFFFFFF); } else { v15 = *(_DWORD *)(hddmbelusageattrib8 - 4); *(_DWORD *)(hddmbelusageattrib8 - 4) = v15 - 1; v12 = v15; } if ( v12 <= 0 ) std::string::_Rep::_M_destroy(v11, v20); } }
最新发布
10-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值