I am writing a C program like the following where I am assigning a value to a variable
pointed by a global pointer, which is being changed by a function call on the right side of the assignment.
But the change occurs to the location where it pointed before.
So for the following code, it prints
“GP:5 P:5 GPV:11” ,
where it should be
“GP:10 P:10 GPV:9”
I tried it compiling with both -O2 and -O0. Same output.
I know that it is fixed if I just break the assignment into 2 lines. But the project I am working on has lots of places like this.
Is this possible to make it work like I want without breaking it into 2 lines?
Any suggestion is highly appreciated.
#include <stdio.h>
int * gp;
// volatile int *gp; // I tried these two.
// int * volatile gp; // Didn't help.
int func(int *p)
{
*p = 5;
gp = p;
return *p;
}
int main()
{
int p = 7;
int gp_v;
gp = &gp_v;
*gp = 8;
*gp = func(&p) + *gp;
gp_v ++;
printf("GP:%d P:%d GPV:%d\n", *gp, p, gp_v);
return(0);
}
This line has unspecified behavior:
The C standard does not specify the order that arguments are evaluated in within expressions, so the compiler is free to execute
func(&p)either before or after reading*gpfor computing the addition. Likewise, it can evaluate the*gpon the left-hand side of the assignment (to determine that address where it’s storing the result to) before or after it evaluates the value it’s storing.You need to break up your statement into separate statements in order for it to have well-defined behavior. Either of these would work, but they have different semantics: