Dženan
Dženan

Reputation: 3395

Why doesn't reinterpret_cast convert 'unsigned char' to 'char'?

I am trying to compile this library using MSVC10, and this function is giving me headache:

/*! \brief Read bytes from a \c std::istream
    \param is The stream to be read.
    \param data A pointer to a location to store the bytes.
    \param size The number of bytes to be read.
*/
void _read(std::istream &is, unsigned char *data, int size)
{
    for (int i=0; i < size ; ++i )
      is.get(static_cast<char>(data[i]));
}

error C2664: 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::get(_Elem &)' : cannot convert parameter 1 from 'char' to 'char &'

The original used static_cast, so I try with reinterpret_cast as suggested elsewhere but that fails too:

error C2440: 'reinterpret_cast' : cannot convert from 'unsigned char' to 'char'

This library comes with unix makefiles. What is the best way to resolve this compile error?

Upvotes: 4

Views: 12565

Answers (4)

rodrigo
rodrigo

Reputation: 98416

Because you need a char& that is a reference to char but the result of the cast is an r-value, and so not bindable to the reference.

You need something like:

is.get(reinterpret_cast<char&>(data[i]));

But in this particular case you can / should use static_cast<char&>:

is.get(static_cast<char&>(data[i]));

Upvotes: 3

leemes
leemes

Reputation: 45695

In addition to the other answers which cope with the casting problem:

Why don't you just use istream::read to read size bytes at once? This avoids your hand-crafted for-loop and should be faster.

void _read(std::istream &is, unsigned char *data, int size) {
    is.read(reinterpret_cast<char*>(data), size);
}

Upvotes: 1

AnT stands with Russia
AnT stands with Russia

Reputation: 320621

Because reinterpret_cast does not work that way, by definition.

In order to perform memory re-interpretation, you have to apply reinterpret_cast to pointers or references. If you want to reinterpret unsigned char data as char data, you actually have to convert to char & type, not to char type.

In your case that would be

is.get(reinterpret_cast<char &>(data[i]));

Or you can go the pointer route and do

is.get(*reinterpret_cast<char *>(&data[i]));

(which is the same thing).

Upvotes: 13

Remy Lebeau
Remy Lebeau

Reputation: 596938

Try this instead:

void _read(std::istream &is, unsigned char *data, int size)
{
    for (int i=0; i < size ; ++i )
      is.get(reinterpret_cast<char*>(data)[i]);
}

Upvotes: 1

Related Questions