Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a pointer for casting char* to unsigned char*

I'm writing some code that uses the fstream read() function and this function expects a char* as the buffer. Later on, I want to work with the bytes in this buffer as unsigned chars, so I'm either going to have to: 1. declare the buffer as a char* and then do static_casts for each element later, 2. declare the buffer as unsigned char* and then do a reinterpret_cast when I pass it to the read function, or 3. declare the buffer as a char* and also create a casted pointer that I use for accessing the buffer as an unsigned char.

Here's a snippet:

char* buf = new char[512];
unsigned char* ubuf = reinterpret_cast<unsigned char*>(buf);

    fstream myfile;

    myfile.open("foo.img");

    myfile.seekg(446);
    myfile.read(buf, 16);
    //myfile.read(reinterpret_cast<char*>(buf), 16);

int bytes_per_sector = ubuf[1] << 8 | ubuf[0];
...

I like this way because I only have to cast once and I can just access the buffer as either type without doing a cast every time. But, Is this a good practice? Is there anything that can go wrong here? Using reinterpret_cast makes me a little nervous because I don't normally use it and I've been told to be careful with it so many times.

like image 677
shwoseph Avatar asked Feb 01 '15 00:02

shwoseph


People also ask

Can I cast unsigned char to char?

However, from i=128:255 the chars and the unsigned chars cannot be casted, or you would have different outputs, because unsigned char saves the values from [0:256] and char saves the values in the interval [-128:127]).

What is unsigned char* in C?

unsigned char is a character datatype where the variable consumes all the 8 bits of the memory and there is no sign bit (which is there in signed char). So it means that the range of unsigned char data type ranges from 0 to 255.

What happens when you cast a char pointer to an int pointer?

When casting character pointer to integer pointer, integer pointer holds some weird value, no where reasonably related to char or char ascii code. But while printing casted variable with '%c', it prints correct char value. Printing with '%d' gives some unknown numbers.

How to make char unsigned in C?

unsigned char ch = (unsigned char)212; printf("%u", (unsigned int)ch); In general, the standard leaves the signedness of char up to the implementation. See this question for more details. Save this answer.


1 Answers

In this case a reinterpret_cast is fine, for 2 reasons:

  1. The (signed) char and unsigned char types are required to have the same "representation and alignment". This means that there is not going to be a difference in the data (it will be bit-per bit exact), or how long the buffer is interpreted to be.

  2. File reading functions typically use char* just as a generic data-access type. They can't use void* because the type void has an specifically undefined length and representation. char, however, does. So they can use it to read/write a series of bytes.

Actually, file-functions are oftentimes intended to have data be reinterpreted as/from something else. It allows you to have a struct like

typedef struct structSomeStruct
{
    char name[8]; // a basic, fixed length, string
    unsigned long i; // a 32 bit value
    float x, y, z, w;
} SomeStruct;

Or

class SomeStruct
{
    public:
        char name[8];
        unsigned long i;
        float x, y, z, w;
        
        SomeStruct()
        {
            // ...
        }
};

And store it to a file using something like:

SomeStruct st;

// populate the st data structure

// file.write(char* start_of_data, size_t number_of_bytes);
file.write(reinterpret_cast<char*>(&st), sizeof(SomeStruct));

And read it similarly.

like image 163
Wolfgang Skyler Avatar answered Oct 18 '22 13:10

Wolfgang Skyler