使用constexpr函数替代reinterpret_cast

gal*_*p1n 12 c++ crc32 reinterpret-cast constexpr c++14

下面,您将找到一个用于CRC32计算的constexpr字符串文字.

我不得不重新解释字符串文字字符charunsigned char.因为reinterpret_cast在constexpr函数中不可用,所以解决方法是手动的两个补码的小实用函数,但我对它有点失望.

处理这种操作是否存在更优雅的解决方案?

#include <iostream>

class Crc32Gen {
    uint32_t m_[256] {};

    static constexpr unsigned char reinterpret_cast_schar_to_uchar( char v ) {
        return v>=0 ? v : ~(v-1);
    }
public:
    // algorithm from http://create.stephan-brumme.com/crc32/#sarwate
    constexpr Crc32Gen() {
        constexpr uint32_t polynomial = 0xEDB88320;
        for (unsigned int i = 0; i <= 0xFF; i++) { 
            uint32_t crc = i; 
            for (unsigned int j = 0; j < 8; j++) 
                crc = (crc >> 1) ^ (-int(crc & 1) & polynomial);
            m_[i] = crc;
        }
    }

    constexpr uint32_t operator()( const char* data ) const { 
        uint32_t crc = ~0; 
        while (auto c = reinterpret_cast_schar_to_uchar(*data++))
            crc = (crc >> 8) ^ m_[(crc & 0xFF) ^ c];
        return ~crc; 
    } 
};
constexpr Crc32Gen const crc32Gen_;

int main() {
    constexpr auto const val = crc32Gen_( "The character code for É is greater than 127" );
    std::cout << std::hex << val << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

编辑:在这种情况下,static_cast<unsigned char>(*data++)就够了.

eca*_*mur 9

标准不保证二者的补充; 在第3.9.1条中:

7 - [...]整数类型的表示应使用纯二进制计算系统定义值.[ 例如:本国际标准允许积分类型的2的补码,1的补码和带符号的幅度表示.- 结束例子 ]

因此,任何假设两个补码的代码都必须手动执行适当的操作.

也就是说,您的转换功能是不必要的(可能不正确); 对于有符号到无符号的转换,您只需使用标准积分转换(4.7):

2 - 如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模2 n,其中n是用于表示无符号类型的位数).[ 注意:在二进制补码表示中,此转换是概念性的,并且位模式没有变化(如果没有截断).- 结束说明 ]

更正代码,使用static_cast::

constexpr uint32_t operator()( const char* data ) const { 
    uint32_t crc = ~0; 
    while (auto c = static_cast<unsigned char>(*data++))
        crc = (crc >> 8) ^ m_[(crc & 0xFF) ^ c];
    return ~crc; 
} 
Run Code Online (Sandbox Code Playgroud)

  • @ galop1n添加128假定`char`是带符号的8位二进制补码类型,标准不保证所有属性. (5认同)
  • @ galop1n但是`CHAR_BIT`可以大于8; 它只需要*至少*8(C,5.2.4.2.1,参考3.9.1p3). (4认同)