Paeryn wrote: ↑Thu Apr 18, 2019 2:18 am
These aren't complex things, it's no harder to give the correct information from the get go. The hardest thing is to say
if you want to guarantee a char can have a range -128 to 127 then use signed char, if you want a guaranteed range of 0 to 255 then use unsigned char. If you only care about having a range of 0 to 127 then you can use char unqualified (or know that the software will only ever be compiled on a certain platform)
Thats right, but it isn't always as simple as that

They are three distinct types. The standard library functions expect unadorned "char". So "signed char" and "unsigned char" are incompatible. Furthermore if you do: unsigned char str = "hello, world"; It will fail on both x86 and ARM.
The only safe option is the compiler flag (which all compilers have AFAIK) for just this reason.
-funsigned-char makes x86 chars behave the same as ARM ones. I prefer unsigned as you don't get any unexpected sign-extension when characters are accessed, and its much easier for ARM to deal with.
Code: Select all
#include <stdio.h>
int
main( void )
{
const unsigned char *str = "hello world";
puts(str);
}
produces these two warnings on both x86 and ARM:
Code: Select all
hello.c: In function 'main':
hello.c:7:30: warning: pointer targets in initialization of 'const unsigned char *' from 'char *' differ in signedness [-Wpointer-sign]
const unsigned char *str = "hello world";
^~~~~~~~~~~~~
hello.c:8:8: warning: pointer targets in passing argument 1 of 'puts' differ in signedness [-Wpointer-sign]
puts(str);
^~~
In file included from hello.c:2:
/usr/include/stdio.h:697:12: note: expected 'const char *' but argument is of type 'const unsigned char *'
extern int puts (const char *__s);
^~~~
As for main()'s signature, it is only necessary to change "void main( void )" to "int main( void )" -
there is no need to actually return anything! A simple change which shouldn't upset beginners.