Conversion between uint8 and char in C

13,998

Solution 1

Both types are 8bits long. The difference comes with signedness.

  • The uint8 type is unsigned.
  • The char type should be signed in your case. Actually, it is compiler dependent, but most compilers consider the char type as signed by default and have an option to force char type as unsigned if needed. See the C99 standard document reference §6.2.5p15:

The implementation shall define char to have the same range, representation, and behavior as either signed char or unsigned char.

CHAR_MIN, defined in limits.h, will have one of the values 0 or SCHAR_MIN, and this can be used to distinguish the two options.

Solution 2

char and uint8 have both something in common, and that's important: they're both 8 bits integers. Now two questions

  • is/are this/these 8 bits integer(s) signed, or unsigned?

And more importantly

  • does it matter in your case?

I.e. do you want to send to the function an array made of integers for which it is important to have them considered signed? For instance, if the function would do something like that,

if (charvalue < 0) { ... 

or if you want the function to pay attention to the signedness of the bytes (if that'd be possible) ; if the function would do that, and sign would matter: sending a 255 is positive, but considering the byte signed, that'd be interpreted as -1...

But that doesn't make sense since the function takes uint8 * (actually inside the function the devs may have used char to treat bytes individually, and use their signedness, but in this case having a function signature like that would be very misleading!)

So the E2PROM is treating bytes unsigned, and you can safely cast the pointer given to the function to remove the warning,

CyBle_StoreAppData((uint8 *)Prefix,datastack_ROM,10,0);

or simply

uint8  Prefix[10];

if that doesn't cause other problems/warning with the rest of your code.

Solution 3

uint8                   Container_ID[10];

Thats an unsigned 8 bit integer with possible values from 0 to 255

char                    Prefix[10];

In your case a signed 8 bit char with integer values from -127 to +128

Because they are not the same sign type, you get a conversion warning, as you should.

Share:
13,998

Related videos on Youtube

abdullah cinar
Author by

abdullah cinar

Updated on September 15, 2022

Comments

  • abdullah cinar
    abdullah cinar over 1 year

    I have an API that implements a writing operation to EEPROM. Here is its declaration:

    CYBLE_API_RESULT_T CyBle_StoreAppData (uint8 * srcBuff, const uint8 destAddr[], uint32 buffLen, uint8 isForceWrite);
    

    It is working well when I call this function and send an array parameter to srcBuff which has been declared as uint8 type.

    The problem is, I need to send char array pointer to it. I was thinking that char is already a uint8, but I get a compiler warning if I send a char array pointer to that function instead of uint8. Why can't I use char instead of uint8 ? Here are 2 examples of calling that function:

    static const uint8      datastack_ROM[dedicatedRomSize] = {0};
    uint8                   Container_ID[10];
    char                    Prefix[10];
    
    //Call the function with Container_ID which has been declared as uint8. This is working.
    CyBle_StoreAppData(Container_ID,datastack_ROM,10,0);
    
    //Call the function with Prefix which has been declared as char. This is NOT working.
    CyBle_StoreAppData(Prefix,datastack_ROM,10,0);
    

    Here is the warning for the second call:

    passing char[10] to parameter of type 'uint8 *' converts between pointers to integer types with different sign.

    Aren't char and uint8 same?

  • abdullah cinar
    abdullah cinar about 8 years
    I didn't think that it is compiler dependent. I had found this link link. But if i declare the Container_ID as unsigned, i can not use string function which i use them for another job. So i should cast it like at the @Joachim's answer right?
  • abdullah cinar
    abdullah cinar about 8 years
    I didn't think that it is compiler dependent. I had found this link link. But if i declare the Container_ID as unsigned, i can not use string function which i use them for another job. So i should cast it like at the @Joachim's answer right?
  • 2501
    2501 about 8 years
    @abdullahcinar Yes you can cast it, assuming your architecture has 8 bits per byte and two's complement, which is almost certain it does.
  • abdullah cinar
    abdullah cinar about 8 years
    Yes, i checked it and it's true. So i can continue with that. Thanks a lot to all of you who have an answer for this question.
  • greydet
    greydet about 8 years
    See my edit, I added a reference to the C standard. But yes you could cast it as proposed.
  • plugwash
    plugwash about 8 years
    I'm pretty sure gcc gives the "differe in signedness" conversion warning in this case even on platforms where char is unsigned.
  • 2501
    2501 about 8 years
    @plugwash No I can quote you the standard on that. char is literally identical to either signed char or unsigned char, except it is it's own type. (Please don't downvote based on subjective feelings towards me. Yesterday I was only trying to help you and made a mistake, you can check the comments, where I apologized for my error.)
  • abdullah cinar
    abdullah cinar about 8 years
    Thank you :) This was explanatory. I confirmed that my compiler had considered that as signed. So i have used a cast operation and it is working very well. Thank you all.
  • M.M
    M.M about 8 years
    @abdullahcinar your link only refers to a particular compiler and platform. It's normal for ARM targets to default plain char to unsigned. Since there are more ARM CPUs than PCs in the world, perhaps it is more correct to say that char is usually unsigned !
  • 2501
    2501 about 8 years
    @plugwash I have just checked with gcc 5.1.0 with -Wall -Wextra -Wconversion and it doesn't give a warning when the signedness of char and int8_t match, and it gives an error when they don't match as per my answer. So that is a practical example. The theoretical aspect is explained in: C11 6.2.5., pt 15. I think that addresses you concern as invalid.