4
votes

I've a function which take an uint8_t * argument :

uint8_t* ihex_decode(uint8_t *in, size_t len, uint8_t *out)
{
    uint8_t i, hn, ln;

    for (i = 0; i < len; i+=2) {
        hn = in[i] > '9' ? (in[i]|32) - 'a' + 10 : in[i] - '0';
        ln = in[i+1] > '9' ? (in[i+1]|32) - 'a' + 10 : in[i+1] - '0';

        out[i/2] = (hn << 4 ) | ln;
    }

    return out;
}

I use this function with :

uint8_t data[SPM_PAGESIZE]; // SPM_PAGESIZE = 256 bytes
uint8_t sysex_data[SPM_PAGESIZE/2];
ihex_decode(data, strlen(data), sysex_data);

But in this case, my compiler (avr-gcc) return a warning :

main.c|89|warning: pointer targets in passing argument 1 of 'strlen' differ in signedness /usr/include/string.h|399|note: expected 'const char *' but argument is of type 'uint8_t *'

So, i've found a solution by type casting the data var :

ihex_decode(data, strlen((const char *)data), sysex_data);

The warning disappears but I wonder if this solution is safe.

Is there a better way ?

Thanks

4
Why are you using uint8_t for a type that is apparently char ? - Paul R
Because my program is running on microcontroller. So i can't have negative value. - Loïc G.
That makes no sense. The input data appears to be ASCII hex, so it's naturally char. The output data of course would remain as uint8_t. - Paul R
So you suggest me to change uint8_t *in to char *in ? - Loïc G.
The problem here isn't using uint8_t, the problem is people who believe that char is some mysterious magical type. If you check carefully, you will find that there are no negative numbers in the ASCII table. So using uint8_t for ASCII characters is perfectly fine, in fact it is the most proper type to use. The C standard happens to use char type for historical/illogical reasons, that's why you get the warning. Just typecast away such warning, uint8_t is more correct. - Lundin

4 Answers

4
votes

It is safe. The error has to do with mixing unsigned integers of 8 bits with characters, that are signed if you use just char.

I see, however, that the function accepts uint8_t and does character arithmetic, so it should accepts chars (or const chars, for the matter). Note that a character constant 'c' is of type char, and you're mixing signed and unsigned in the expressions inside ihex_decode, so you have to be careful to avoid overflows or negative numbers treated as big positive numbers.

A last style note. As in is not modified, it should read const uint8_t* in (or const char* in, as of above) in the parameters. Another style error (that may lead to very bad errors) is that you accept len as size_t, but declare the i loop variable as uint8_t. What if the string is more than 255 bytes in length?

1
votes

Everything which is non-const * can be safely casted to const * in C. It's save.

1
votes

This is safe. The warning (I think) pops up because you're casting from unsigned to signed.

0
votes

Its safe, the range of char < uint8_t.