简体   繁体   中英

casting to unsigned char not working

I have a really irritating problem. This is the buffer structure i am using

typedef struct BufferDescriptor {
   char * ca_head ;    /* pointer to the beginning of character array (character buffer) */
   int capacity ;      /* current dynamic memory size (in bytes) allocated to character buffer */       
   char inc_factor;    /* character array increment factor */
   int addc_offset ;    /* the offset (in char elements) to the app-character location */
   int mark_offset ;   /* the offset (in chars elements) to the mark location */
   char r_flag;        /* reallocation flag */
   char mode;          /* operational mode indicator*/

} Buffer ;

I cannot make any changes to above code. The inc_factor is supposed to be able to take values from 0 to 255.

therefore in the function where a buffer is created, i do the following so as to ensure that the inc_factor is not negative:

Buffer* b_create(int init_capacity, char inc_factor,char o_mode){
    Buffer* buffer = (Buffer*)malloc(sizeof(Buffer));
    buffer->ca_head=(char*)malloc(sizeof(char)*init_capacity);

    buffer->inc_factor=(unsigned char)(inc_factor);

But the following line gives out a negative number:

printf("inc factor = %d",buffer->inc_factor);

What am I doing wrong here ? Plz Help.

You'll need to cast wherever you want to use the value as unsigned .

char value = 255;
printf("%d\n", value);
printf("%d\n", (unsigned char) value);

Should output:

-1
255

You are formatting a signed variable as a signed value, so of course it will output a negative value if the variable exceeds 127. That is what happens when you store an unsigned value into a signed variable - it wraps around to the negative. If you cannot change the variable type itself, then you have to change how it is being formatted (type-casting a signed value to an unsigned type and then assigning to a signed variable is pointless):

printf("inc factor = %u", (unsigned char) buffer->inc_factor); 

Or:

printf("inc factor = %d", (unsigned char) buffer->inc_factor); 

When you define a type of a variable, you're actually telling the compiler how it should interpret the bits from memory. Therefore, casting a char into unsigned char doesn't change the bits in memory, but actually affects how the data affects the operations it is used in.

In your case, you cast it, but store back into a signed char. When the data is read by the compiler (remember, no bits are modified), it is interpreted as a signed char, because that is the type that of BufferDescriptor.inc_factor .

The simplest solution is to cast it when you use it:

printf("inc factor = %d",(unsigned char)buffer->inc_factor);

BUT there is serious and dangerous bug here. The compiler will push the arguments to the stack as they type it interprets (in this case, a single-byte unsigned char). The problem is that the printf function removes the parameter from the stack as they type you tell it to interpret (in this case, %d normally means a 4-byte integer). As you can see, there are 3 bytes that are missing. The printf will forcefully read those extra three bytes, so it will actually get invalid data from memory.

To fix this, push it to the stack as a 4-byte integer:

printf("inc factor = %d",(int)((unsigned char)buffer->inc_factor));

Notice that before we cast it to a 4-byte integer, we cast it as an unsigned char. This is to force the compiler to first interpret the bits as unsigned then to zero-extend (and not sign extend) the remaining 3-bytes.

Hope this helps =)

In an 8 bit value of char, -1 = 1111 1111 in binary and 255 = 1111 1111 in binary. So it's the same representation it all just depends on how you cast it.

If you don't cast printf("inc factor = %d",buffer->inc_factor); you will print -1 since %d is trying to print a signed decimal. If you cast the printing value like:

printf("inc factor = %d", (unsigned char) buffer->inc_factor);

you will print 255. You should store a local variable as:

unsigned char unsigned_char_inc_factor = (unsigned char) buffer->inc_factor;

and just used unsigned_char_inc_factor afterwards.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM