1

prog i wrote works for some values of integer but not for all... why ??

program output

int value is abcdef78
first byte is 78 addr is 2686741
second byte is ffffffef addr is 2686742
third byte is ffffffcd addr is 2686743
fourth byte is ffffffab addr is 2686744

expected output

int value is abcdef78
first byte is 78 addr is 2686741
second byte is ef addr is 2686742
third byte is cd addr is 2686743
fourth byte is ab addr is 2686744

Process returned 0 (0x0)   execution time : 0.015 s
Press any key to continue.

Code:

#include <stdio.h>
#include <stdlib.h>

int main()
{

    int i=0xabcdef78;
    int *ip;

    printf("int value is %x\n",i);   //  *ip contents of address

    char c;
    char *cp;
    cp=&i;
    c = *cp;
    printf("first byte is %x addr is %d\n",*cp++,cp);
    printf("second byte is %x addr is %d\n",*cp++,cp);
    printf("third byte is %x addr is %d\n",*cp++,cp);
    printf("fourth byte is %x addr is %d\n",*cp++,cp);

    return 0;
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
Pushkar
  • 11
  • 1

3 Answers3

0

The reason is that your char is getting promoted to int with sign extension. 0xef in binary form is:

1110 1111

and it get promoted to an 32 bit integer with a sign extension like this:

1111 1111  1111 1111  1111 1111  1110 1111

While 0x78 in binary form is:

0111 1000

The most significant bit is 0 so it get promoted like this:

0000 0000  0000 0000  0000 0000  0111 1000

There are two solutions:

  1. Do not print your char as a 32 bit value, i.e. use %hhx instead of %x.

  2. Make your char unsigned, i.e. unsigned char *cp instead of char *cp

Andriy Berestovskyy
  • 8,059
  • 3
  • 17
  • 33
0

You should modify your code like

#include <stdio.h>

int main(void)
{
    int i = 0xabcdef78;

    printf("int value is %x\n", i);   //  *ip contents of address

    unsigned char *cp;
    cp = (unsigned char *)(&i);

    printf("1st byte is 0x%02X addr is %p\n", cp[0], (void *)(&cp[0]) );
    printf("2nd byte is 0x%02X addr is %p\n", cp[1], (void *)(&cp[1]) );
    printf("3rd byte is 0x%02X addr is %p\n", cp[2], (void *)(&cp[2]) );
    printf("4th byte is 0x%02X addr is %p\n", cp[3], (void *)(&cp[3]) );

    return 0;
}

As you can see:

  1. I changed the format specifier for address: must be %p and passed arg must be void *
  2. I removed the pointer increment because it is UB. Take a look at this famous SO question. If you want to inc your pointer, you must inc it after printf.
  3. You must use unsigned char to point bytes of your integer, otherwise, asu you are facing, values greater then 7F will be considered as negative.

OUTPUT

int value is abcdef78
1st byte is 0x78 addr is 0x7ffdda43fc8c
2nd byte is 0xEF addr is 0x7ffdda43fc8d
3rd byte is 0xCD addr is 0x7ffdda43fc8e
4th byte is 0xAB addr is 0x7ffdda43fc8f
LPs
  • 16,045
  • 8
  • 30
  • 61
-1

Delete the statement

    int *ip;

as you never use it (not important). Then:

Instead of

printf("first byte is %x addr is %d\n",*cp++,cp);
printf("second byte is %x addr is %d\n",*cp++,cp);
printf("third byte is %x addr is %d\n",*cp++,cp);
printf("fourth byte is %x addr is %d\n",*cp++,cp);

use

printf("first byte  is %hhx, addr is %ld\n", *cp++, cp);
printf("second byte is %hhx, addr is %ld\n", *cp++, cp);
printf("third byte  is %hhx, addr is %ld\n", *cp++, cp);
printf("fourth byte is %hhx, addr is %ld\n", *cp++, cp);

as the logic of your program is correct, but the output is bad formatted.

MarianD
  • 13,096
  • 12
  • 42
  • 54
  • This doesn't fix the undefined behaviour issue. – r3mainer May 25 '17 at 08:41
  • @squeamis - You are perfectly right, thanks. I wanted correct my answer but meanwhile [LPs](https://stackoverflow.com/users/3436922/lps) put a correct one. – MarianD May 25 '17 at 10:03