0

So am trying to write a trivial program just for fun. Intent is to print the value of an integer using char pointer

So you can see I have an integer a, which I print and then I use a char* b to get the higher byte location of the integer and then get the lower byte using post-increment operation of char* b

But on https://code.sololearn.com the line which prints *b and *b++, throws warning for *b++. Am interested in knowing what is the way to remove that warning.

#include <stdio.h>

int main(void) {

    int a = 0xaabb;

    printf("%x\n",a);

    unsigned char *b = (unsigned char*) &a;

    printf("%x%x\n",*b, *b++);

    return 0;
}
Tahseen
  • 1,027
  • 1
  • 12
  • 32
  • Use a `union`, e.g. `typedef union { unsigned char bytes[4]; int n; } uc2n;` Then `uc2n convert = { .n = 0xaabb };` now you can use `convert.bytes[0] - convert.bytes[3]` to access each byte of the `int`. – David C. Rankin Feb 28 '20 at 19:58
  • You are changing the approach completely. I understand the array approach. I was trying to understand warning with post-increment in the pointer approach – Tahseen Feb 28 '20 at 20:07
  • It would be nice to know what the exact error message is. Beyond that, since you've done a post-increment, your final print statement will print *b twice. I am not sure if that was your intent or not. – Frank Merrow Feb 28 '20 at 20:11
  • 1
    @FrankMerrow not necessarily. Not only is the order of evaluation not specified, but the post-increment might be done before the other `b` is placed as an argument. A post-increment happens at some time between that `b` being used, and the next sequence point. – Weather Vane Feb 28 '20 at 20:13

1 Answers1

2

The problem you are having is due to the order of evaluation of the parameters passed to printf being unspecified. You are attempting to pass *b, *b++. Since the order in which the parameters are evaluated is not specified, the compiler cannot guarantee what the value of *b will be. If *b++ is evaluated first, then the first parameter will be one greater than the second. If *b++ is evaluated second, the both parameters are the same.

That is the reason you receive a warning similar to:

warning: operation on ‘b’ may be undefined [-Wsequence-point]

The sequence of evaluation of the parameters is unspecified making the operation on b undefined.

If you want to correct the warning without using a union, then you can simply add one to b, e.g.

#include <stdio.h>

int main(void) {

    int a = 0xaabb;

    printf("%x\n",a);

    unsigned char *b = (unsigned char*)&a;

    printf ("%x%x\n",*b, *(b + 1));

}

or use a second pointer, e.g.

#include <stdio.h>

int main(void) {

    int a = 0xaabb;

    printf("%x\n",a);

    unsigned char *b = (unsigned char*)&a;
    unsigned char *c = b + 1;

    printf ("%x%x\n",*b, *c);

}
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • 1
    If the second argument is evaluated first, the post-increment is not guaranteed to happen before the other `b` is accessed because there is no sequence point yet. – Weather Vane Feb 28 '20 at 20:17
  • Can you elaborate "Since the order in which the parameters are evaluated is not specified" ? printf knows first *b would come and then *b++ – Tahseen Feb 28 '20 at 20:18
  • 2
    @Tahseen *printf knows first *b would come and then *b++* No, it doesn't "know" that. Just because `*b` is to the left of `*b++` in the code you wrote does not mean that `*b` will be evaluated before `*b++`. See https://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points – Andrew Henle Feb 28 '20 at 20:20
  • 1
    You have `printf ("..", param1, param2)`. The order in which `param1` and `param2` are evaluated is not specified by the standard. So either can happen. If the order of evaluation is `param1, param2`, then the post increment is taken after the parameter has been evaluated and `param1 == param2` for the call, If the order is `param2, param1` the post increment is applied and the parameters seen by `printf` differ -- but you have no guarantee of knowing which will occur. – David C. Rankin Feb 28 '20 at 20:21
  • 1
    @Tahseen `printf` neither knows nor cares which argument was evaluated or placed first. It only knows where to find them. – Weather Vane Feb 28 '20 at 20:24