Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacing reinterpret_cast with better alternatives?

I have a few places in my project where I use reinterpret_cast to read/write an unsigned integer from a stream. Consider the following functions:

size_t ReadSize(std::stringstream& stream) {
  char buf[sizeof(size_t)];
  stream.read(buf, sizeof(size_t));
  return *(reinterpret_cast<size_t*>(buf));
}

void WriteSize(std::stringstream& stream, size_t n) {
  stream.write(reinterpret_cast<char*>(&n), sizeof(size_t));
}

I started to feel a bit uncomfortable about using reinterpret_cast, even though I've had no problems with it, so I'm wondering, is there a better alternative to this? Assuming I just have 4 bytes in the stream that are supposed to represent this integer.

static_cast isn't applicable here either, I think. Any tips?

P.S. I am not currently concerned about portability or other platform-specific problems that may arise from using reinterpet_cast. I am writing this for a Windows machine.

like image 727
Samuel Moriarty Avatar asked Jan 07 '23 07:01

Samuel Moriarty


2 Answers

While the read (and write) functions are specified to take a char*, you don't actually have to pass an array of characters, just cast a pointer to the actual variable right there in the read (or write) call instead:

std::size_t size;
if (stream.read(reinterpret_cast<char*>(&size), sizeof(size_t)))
    return size;
return 0;  // Or something else on error

On an unrelated note, I recommend you change the stream parameter to a std::istream reference instead, then you can use the function for any input stream.

like image 59
Some programmer dude Avatar answered Jan 18 '23 16:01

Some programmer dude


So the problem with your code, is that if a little-endian system writes the data, and a big-endian system reads it.

Here, reinterpret_cast<> will take the bit image and apply it regardless of any data incompatibilities.

The order of preference is :-

  • const_cast is used to remove/add only const.
  • dynamic_cast converts pre-created objects to compatible base/derived.
  • static_cast uses compile-time information to perform the same form of conversion as dynamic_cast
  • reinterpret_cast treats the memory as a union of source and destination.
  • C cast (void*)f; converts the type using one of reinterpret_cast / static_cast.

So avoid C cast. This is because you can't really tell what the compiler will choose. const_cast / dynamic_cast don't solve your issues.

So the best choice is reinterpret_cast.

like image 22
mksteve Avatar answered Jan 18 '23 15:01

mksteve