I'm trying to implement something that will take in arbitrary bits of data (which are known at compile time) and calculate their CRC as a consteval
, so I can use it to e.g. index such data with integer keys without any runtime overhead. I have it working when the input is a char string literal, but I'm struggling to make it work when the input is a wchar_t
string literal.
I'm getting a fairly cryptic error...
error: accessing value of '"T\000e\000s\000t\000\000"' through a 'const char' glvalue in a constant expression
... which seems to be caused by using reinterpret_cast within a constexpr context (which is apparently not allowed)
My question is, is there any way of interpreting arbitrary data as a plain old array of bytes anyway? I don't care how ugly or lacking in portability it is (as long as it all happens at compile time). For now, just solving the case with an array of wchar_t
as input would be enough. Obviously, I could "just" reimplement the CRC calculations for each type I want to handle separately, but I would rather not do that if at all possible (and indeed it would be quite tricky for anything more complex than an array of POD)
For reference, the failing code is as follows:
// Details of CRCInternal omitted for brevity
template <size_t len> consteval uint32_t CRC32(const char (&str)[len])
{
return CRCInternal::crc32<len - 1>(str) ^ 0xFFFFFFFFu;
}
template <size_t len> consteval uint32_t CRC32FromWide(const wchar_t (&filename)[len])
{
return CRC32(reinterpret_cast<const char(&)[len * sizeof(wchar_t)]>(filename));
}
void main()
{
CRC32FromWide(L"Test"); // <==== Error
}