In commit “Make uint256 Span-convertible by adding ::data()” (5d1f1d93154f3cee384e121963940141603e01f7)
I think it’d be better to avoid doing potentially unsafe reinterpret_casts when really we only need to cast char
pointers to unsigned char
pointers.
My concern is that providing this function might make it too easy to write code that looks like it is hashing vector<uint256>
or Optional<uint256>
or uint256*
data, but actually hashing the outer pointer or container objects instead.
I think we could provide a more limited convenience function, similar to our current CharCast
function that’s just restricted to chars and won’t reinterpret arbitrary spans of objects.
Experimenting a little, the following seems to work well:
0inline unsigned char* UnsignedCharCast(char* c) { return (unsigned char*)c; }
1inline unsigned char* UnsignedCharCast(unsigned char* c) { return c; }
2inline const unsigned char* UnsignedCharCast(const char* c) { return (unsigned char*)c; }
3inline const unsigned char* UnsignedCharCast(const unsigned char* c) { return c; }
4
5//! Safely convert a character array into a span of unsigned chars.
6template<typename T>
7Span<const unsigned char> UnsignedCharSpan(const T& in) { auto span = MakeSpan(in); return {UnsignedCharCast(span.data()), span.size_bytes()}; }
Another advantage of this is allows replacing AsUnsignedChars(MakeSpan(in))
with simpler UnsignedCharSpan(in)
everywhere.