Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why global variable is different from local variable in this function?

Here I have a function named max(a,b) to get the max number out of two. And I found that the value of variable a and b using printf() are different after executing

printf("maxab()=%d after max: a=%d b=%d \n",max(a++,b++),a,b);

when a and b are Global variables and Local variables. Below is my code:

#include<stdio.h>

int max(int a,int b)
{

    if(a>b)
    {
        //printf("In func max():%d %d \n",a,b);
        return a;
    }
    else {
        //printf("In func max():%d %d \n",a,b);
        return b;
    }

}
void jubu_test(void)
{
    int a=1;
    int b=2;    
    printf("maxab()=%d after max: a=%d b=%d \n",max(a++,b++),a,b);  //a=2,b=3
}
int c=2;
int d=1;
void quanju_test(void)
{
    printf("maxcd()=%d  c=%d d=%d \n",max(c++,d++),c,d);    //c=2,d=1
    c=2;
    d=1;
    int f=max(c++,d++);
    printf("maxcd()=%d after max: c=%d d=%d \n",f,c,d);     //c=3,d=2
}   
int main(int argc, char** argv)
{
    jubu_test();
    quanju_test();
}

The result I get on my computer is:

maxab()=2 after max: a=2 b=3
maxcd()=2  c=2 d=1
maxcd()=2 after max: c=3 d=2

My question is: Why in the second output a and b is their original value and why the third output is a+1 and b+1? Why when a and b are Global variables, the value of a and b printed out only changes when we execute max(a++,b++) first? Why when a and b are local variables it doesn't matter?

Thanks! (using gcc 5.3.0 on windows 10)

like image 284
walle Avatar asked Feb 04 '23 18:02

walle


1 Answers

The expression printf(... max(a++,b++),a,b); is undefined behavior as per Why are these constructs (using ++) undefined behavior?.

The evaluation of a++ is not sequenced in relation to the evaluation of a, same for b++ and b. It doesn't matter that there is a sequence point before the function is called, because the sub-expressions may be evaluated before that, in any order.

Undefined behavior = always a bug. Means that the program could have any kind of behavior, print anything, crash & burn etc.

The reason why it is undefined behavior is this, C11 6.5/2:

If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.

(a is a scalar object - not an array or struct etc. a++ causes a side-effect of updating the variable. This is unsequenced in relation of the value computation of a elsewhere in the same expression.)


Not to be confused with unspecified behavior, which means that the program will behave deterministically but you can't know in which way. For example, the order of evaluation of function arguments is unspecified behavior:

int func (void)
{
  static int x=0;
  x++;
  return x;
}

printf("%d %d", func(), func());

This may print either 1 2 or 2 1 and we can't know or assume which applies. The compiler does not need to document this, nor does it have to behave consistently throughout the program. It could pick one order in one case and another order in another case.

Code relying on unspecified behavior is bad, but won't behave completely erratically like code containing undefined behavior.

like image 111
Lundin Avatar answered May 17 '23 08:05

Lundin