2

I have been using some C code I found online, which had compiler warnings with codeblocks on windows 7, as I am learning C and trying to understand the code as part of the learning process I decided to look at the warnings and fix them a few where simple enough, however the first block I fixed I think I understand, but would be grateful if someone could confirm my understanding, the original code snippet in question is

unsigned char buffer[MAX_PATH];

unsigned char text_to_send[MAX_PATH];

unsigned char digits[MAX_PATH];

// example warning with digits when used as below

text_to_send[m] = strtol(digits, NULL, 16);

The warning given is

warning: pointer targets in passing argument 1 of 'strtol' differ in signedness [-Wpointer-sign]|

with a note note: expected 'const char *' but argument is of type 'unsigned char *'

The warning and note is correct to my understanding as digits used on it's own is a constant pointer to the address of digits[0]. When I remove the unsigned declarations and leave them as just type char, the compiler no longer issues warnings when these 3 arrays are used.

My question is that I can see no reason to use unsigned char digits[MAX_PATH] (or for the two declarations which give similar errors], but am I missing something, does the original author know something I have missed?

The code now compiles warning free and works seemingly the same, any input greatly appreciated.

Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
user2176100
  • 97
  • 1
  • 6
  • http://stackoverflow.com/questions/4337217/difference-between-signed-unsigned-char – Kaustav Ray Dec 03 '13 at 02:54
  • `unsigned char text_to_send[MAX_PATH]; text_to_send[m] = strtol(digits, NULL, 16);` That doesn't give a warning? "unsigned char = long"? – John3136 Dec 03 '13 at 02:56
  • No, it does not give an error, but I do see what you mean, I will look at that one also, it can't be right. Thank you for pointing it out. – user2176100 Dec 03 '13 at 03:11

2 Answers2

2

In C language char, unsigned char and signed char are three different, incompatible types. It is true that in specific implementations the representation of char will coincide with that of either signed char or unsigned char, but that still does not make these types compatible.

This, in turn, means that, regardless of implementation's properties, a pointer of type unsigned char * cannot be implicitly converted to type char *. These types are also incompatible. An attempt to perform such implicit conversion is a constraint violation, i.e. it is what we usually call an error (as opposed to what we usually call a warning).

That is what the compiler is trying to tell you with that diagnostic message.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
0

strtol() takes a char *; you're passing it an unsigned char*. The C Standard says that whether a vanilla char is an unsigned char or a signed char An implementation choice. Hence the compiler whine.

It's good practice to set your MS C options to use sane [unsigned] chars via its /J option

Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
  • Sorry, should have mentioned using gcc with codeblocks, I do understand why the warning is there, my question is more why would you declare it unsigned in the first place. – user2176100 Dec 03 '13 at 03:22
  • Because a `char` is an integer. A `signed char` used as an index into an array, for instance, cause problems for codepoints above 0x7F, since it will be a negative index into the array, causing memory corruption or access violations. For the sake of portability and to minimize unwanted problems, explicity declare your `char` types as 'signed' or 'unsigned'. – Nicholas Carey Dec 03 '13 at 17:50
  • 1
    In any case, still `char`, `signed char` and `unsigned char` are three different types, not compatible with each other. Even in implementations where `char` is unsigned, `char` is still considered incompatible with `unsigned char`. This means that regardless of implementation, `char *` and `unsigned char *` are incompatible pointer types, which cannot be mixed. – AnT stands with Russia Dec 03 '13 at 18:12