0
int in=0xeef01f88;
int * ipoi=∈
char*cpoi=(char*)ipoi;
cout<<std::hex<<(int)*ipoi<<" "<<(int)*(cpoi)<<" "<<(int)*(cpoi+1)<<" "<<(int)*(cpoi+2)<<endl;

When I compile this on Cxxdroid (Android compiler) it works perfectly as it should so cout from char pointers gives values of separate bytes like:

eef01f88 88 1f f0.

Another way when I compile the same code on Windows using GNU GCC COMPILER I got this output:

eef01f88 ffffff88 1f fffffff0.   

How is it possible? Why the first and third char pointer values has ffffff in themselves? There even aren't any ff values around *(cpoi+1). (f0) Will changing compiler fix the problem?

I am using Code Blocks. It has plenty of compiling options but I already tried every standard available (up to 2011 ISO C language standard). What am I missing?

phuclv
  • 37,963
  • 15
  • 156
  • 475
Gen0me
  • 115
  • 8
  • 1
    Similar: [printf adds extra `FFFFFF` to hex print from a char array](https://stackoverflow.com/q/31090616/995714) – phuclv Jun 22 '19 at 16:40
  • int * to char * Because both pointers can point to the same Byte in memory. And as you see both systems(android windows) have the same hierarchy of bits so the code should work the same. To make you believe its possible I even wrote the string of ints based on casts string <->int. – Gen0me Jun 22 '19 at 16:59
  • string potential_frames(char * source,long long length){ string str; long long i; ... char * i_c=(char*) &i; str=str+*(i_c+3); str=str+*(i_c+2); str=str+*(i_c+1); str=str+*(i_c); return str; } int in=((int)i_str[n*4])*256*256*256+((int)i_str[n*4+1])*256*256+((int)i_str[n*4+2])*256+((int)i_str[n*4+3]); It works on android perfectly. – Gen0me Jun 22 '19 at 17:13
  • Suggest adding a language tag. You mention ISO C in the question but the code sample `cout << std::hex` suggests you are attempting to use C++ (which is a different language to C) – M.M Jun 23 '19 at 05:19
  • Because (1) chars are signed, (2) 0x88 is negative, (3) char is promoted to `int`, and (4) that promotion is sign-extending. – user207421 Jun 23 '19 at 10:56
  • I am using functions from both c and cpp. Sscanf, cout. Here is full code: https://drive.google.com/folderview?id=1py_4hUFxeNF2HuGWFWmNVFpoLtm548Vy – Gen0me Jun 23 '19 at 14:14

1 Answers1

1

char is meant for storing characters, not numeric values, so they can be signed or unsigned depending on the implementation

  • On ARM char is usually an unsigned type because it's more efficient, therefore casting char to int results in a zero extension
  • On pretty much everywhere else char is a signed type by default, so those bytes will be signed extended to int. As 0x88 and 0xf0 are negative, they'll have one bits in the high part

The solution is to avoid char and use signed char or unsigned char instead, or work around by adding the option to change the signness of char (-funsigned-char in gcc). Or even better, use fixed-width types like uint8_t and int8_t

See

phuclv
  • 37,963
  • 15
  • 156
  • 475
  • Thanks. Did -funsigned-char. Seems to work fine. Had more issues thought. With strings. Had to add str.c_string() and also with binary. Had to change 0b values to dec/hex... – Gen0me Jun 23 '19 at 01:27
  • if it helps then kindly accept the answer by clicking the green checkmark. Note that there's no `c_string()` in `std::string`, only `c_str()`. And the signness of `char` is completely **irrelevant** to binary literals 0b... But as warned [here](https://stackoverflow.com/a/46463173/995714) you should never use those options to change the signness of char. Use `uint8_t` or `unsigned char` explicitly – phuclv Jun 23 '19 at 05:07
  • I tried converting some chars as unsigned but some functions dont want to take them. Something in fstream didnt want to let me go through. I still look for solution to this: https://stackoverflow.com/questions/56719858/delete-crashes-program entire code is here: https://drive.google.com/folderview?id=1py_4hUFxeNF2HuGWFWmNVFpoLtm548Vy – Gen0me Jun 23 '19 at 14:23