2

Lately I've been doing a lot of exercises with file streams. When I use fstream.write(...) to e.g. write an array of 10 integers (intArr[10]) I write:

fstream.write((char*)intArr,sizeof(int)*10);

Is the (char*)intArr-cast safe? I didn't have any problems with it until now but I learned about static_cast (the c++ way right?) and used static_cast<char*>(intArr) and it failed! Which I cannot understand ... Should I change my methodology?

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
Bat0u89
  • 610
  • 2
  • 17
  • 25
  • 2
    possible duplicate of [When should static_cast, dynamic_cast and reinterpret_cast be used?](http://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-and-reinterpret-cast-be-used) – Jonathan Leffler Oct 01 '11 at 22:12

1 Answers1

5

A static cast simply isn't the right thing. You can only perform a static cast when the types in question are naturally convertible. However, unrelated pointer types are not implicitly convertible; i.e. T* is not convertible to or from U* in general. What you are really doing is a reinterpreting cast:

int intArr[10];

myfile.write(reinterpret_cast<const char *>(intArr), sizeof(int) * 10);

In C++, the C-style cast (char *) becomes the most appropriate sort of conversion available, the weakest of which is the reinterpreting cast. The benefit of using the explicit C++-style casts is that you demonstrate that you understand the sort of conversion that you want. (Also, there's no C-equivalent to a const_cast.)

Maybe it's instructive to note the differences:

float    q  = 1.5;
uint32_t n  = static_cast<uint32_t>(q);      // == 1, type conversion
uint32_t m1 = reinterpret_cast<uint32_t>(q); // undefined behaviour, but check it out
uint32_t m2 = *reinterpret_cast<const uint32_t *>(&q); // equally bad

Off-topic: The correct way of writing the last line is a bit more involved, but uses copious amounts of casting:

uint32_t m;
char * const pm = reinterpret_cast<char *>(&m);
const char * const pq = reinterpret_cast<const char *>(&q);
std::copy(pq, pq + sizeof(float), pm);
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • Thanks for the reply but now the only thing I realised is that I was using the notorious reinterpret_cast all the time! I still don't see how I can write these 4 bytes of the int into a binary file using fstream.write(char*,int) as I understand there is simply no safe way to convert from an int* to char*. – Bat0u89 Oct 01 '11 at 23:52
  • 2
    @Bat0u89: `reinterpret_cast` is explicitly allowed from `T*` to `char*`, for precisely your sort of situation (serializing). So cast away and be merry! – Kerrek SB Oct 01 '11 at 23:55