使用memcpy初始化位填充结构

时间:2015-07-16 13:13:24

标签: c++ struct standards memcpy

有谁知道为什么初始化位填充结构是一个"坏事"并且不能使用?

例如:

struct parameter_set_t 
{
    std::uint8_t m_profile_idc;
    bool m_constraint_set0_flag: 1;
    bool m_constraint_set1_flag : 1;
    bool m_constraint_set2_flag : 1;
    bool m_constraint_set3_flag : 1;
    bool m_constraint_set4_flag : 1;
    bool m_constraint_set5_flag : 1;
    std::uint8_t m_reserved_zero_2bits : 2;
    std::uint8_t m_level_idc;
};

inline std::uint32_t bswap32(std::uint32_t v )  
{
    std::uint32_t ret_value = 0;
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
    ret_value = __builtin_bswap32(v);
#else
    ret_value = ((v & 0x000000FF) << 24) | ((v & 0x0000FF00) << 8) | ((v & 0x00FF0000) >> 8) | ((v & 0xFF000000) >> 24);
#endif
    return ret_value;
}

//! build from sdp 0xAABBCC string
profile_level_id( const std::string& sdp_value )
{
    //fetch profile_level_id value
    std::uint32_t int_value = std::stoul( sdp_value, nullptr, 16 );

    int_value = bswap32( int_value ) >> 8;

    std::memcpy( &m_parameters, &int_value, sizeof( parameter_set_t ) );
}

1 个答案:

答案 0 :(得分:3)

问题不在于使用std::memcpy,而是用于在不兼容的源和目标类型之间进行复制。

从无符号整数32位读取数据,但它被写入parameter_set_t结构,其大小为24位。因此,uint32_t的8位被丢弃。这给我们留下了两个问题:

  • 丢弃哪8位,最不重要或最重要?
  • 如何将整数的24位分布在struct的24位中?

这两个问题的答案是“它是特定于平台的”,这是一种说“完全不可移植”的好方法。因此,关于此代码段质量的评论中有咒骂。

请注意,如果在parameter_set_t的两个实例之间进行了复制,则使用std::memcpy就可以了。