Aashish Chandra
Aashish Chandra

Reputation: 45

Why is the output different in these two scenarios

Please give me full description.... The first snippet of code has the 'function call' (macro invocation) before the increment operator, and second one has the function call after the increment operator.

  1. #include <stdio.h>
    #define square(x) x*x
    int main()
    {
      int a,b=3;
      a=square (b)++;
      printf("%d%d",a,b);
      return 0;
    }
    

    output:

    124
    

    why is 124 returned here

  2. #include <stdio.h>
    #define square(x) x*x
    int main()
    {
      int a,b=3;
      a=square (b++);
      printf("%d%d",a,b);
      return 0;
    }
    

    output:

    125
    

    and 125 here?

Upvotes: 0

Views: 78

Answers (2)

In addition to Tom's answer, which explains what is happening, here is an example of how you could define a macro for squaring a number safely:

#define SQR(x) (                    \
{                                   \
        __auto_type x_  = (x);      \
                                    \
        x_ * x_;                    \
}                                   \
)

It only has an appearance of x, and therefore it doesn't evaluate it twice. The copy x_ is used instead. Note that variables created in a macro may conflict with other variables created in the function that calls the macro. To avoid name collisions you use special names that shouldn't be used in normal code such as a trailing _.

With this macro, this:

a = SQR(b++);

will be equivalent to this:

a = SQR(b);
b++;

Warning: This works on some compilers as an extension (GCC for example), but it is not standard C.

Another option, if you want standard C, is to use an inline function. It is ok if you want it to work on just one type (there is _Generic in C11, but I never used it, so no idea).

Upvotes: 0

Tom Karzes
Tom Karzes

Reputation: 24100

The thing to keep in mind is that macros provide simple substitution of preprocessor tokens. In particular, they may evaluate their arguments more than once, and if not guarded by parentheses, they may produce unintended reassociation.

In the first example, we have

a=square (b)++;

This expands to:

a=b*b++;

This is actually undefined behavior, since the b and b++ are unsequenced, and b++ modifies b. In your case, you are seeing 12 and 4 for a and b, so it would seem that the first value of b is picking up the incremented value, so you're getting 4*3, but you can't count on this behavior. The final value of b is 4 since it is incremented once.

In the second example, we have:

a=square (b++);

This expands to:

a=b++*b++;

This is again undefined behavior. In your case, it appears that you're getting 4*3 (or 3*4), but again, you can't count on this behavior. The final value of b is 5 since it is incremented twice, but this too is undefined behavior.

Upvotes: 3

Related Questions