Pointer and right evaluation of an expression in C
I have a question in language C. Considerer the following code (which is a minimal example) :
#include <stdio.h>
int f(int**, int*);
int main(int argc, char *argv[])
{
int *u = NULL, t1=0, t2=1;
u = &t1;
printf("t1 : %d\n", t1);
printf("t2 : %d\n\n", t2);
*u = 36;
printf("t1 : %d\n", t1);
printf("t2 : %d\n\n",开发者_运维技巧 t2);
*u = f(&u, &t2);
printf("t1 : %d\n", t1);
printf("t2 : %d\n\n", t2);
return 0;
}
int f(int** p, int* e){
*p = e;
return 24;
}
When I run this program, I get the following result :
t1 : 0
t2 : 1
t1 : 36
t2 : 1
t1 : 24
t2 : 1
What surprises me is that the left part of the expression (i.e. *u):
*u = f(&u, &t2);
is fixed before the processing of the function f. In fact, I was expecting the following result since the function f modifies the pointer u :
t1 : 0
t2 : 1
t1 : 36
t2 : 1
t1 : 36
t2 : 24
Is that normal ? Did I miss something in my C class ?
There is no sequence point in an assignment expression and there is not guaranteed order of evaluation between the left and right operands of an assignment expression. The code you have written does not have well defined behavior in C so the behavior that you are seeing doesn't mean that your compiler is not conforming.
6.5 / 3:
Except as specified later (for the function-call
()
,&&
,||
,?:
, and comma operators), the order of evaluation of subexpressions and the order in which side effects take place are both unspecified.
Although there is a sequence point in the function call, there is no guarantee whether the function is called before or after the evaluation of *u
.
After running your code, I got the answer that you expected. You should check your code more carefully.
Edit: After reading the other answer, I felt I should post my specs. I am running off Visual Studio 2010 64 bit, on Windows 7 Ultimate 64 bit.
When the function is called, the memory location where the return value will be stored is fixed. Although you are changing what u is pointing to, but the assignments(memory location) that would occur in the function call is already fixed.
In fact, if you try
#include <stdio.h>
int f(int**, int*);
int main(int argc, char *argv[])
{
int *u = NULL, t1=0, t2=1;
u = &t1;
printf("t1 : %d\n", t1);
printf("t2 : %d\n\n", t2);
*u = 36;
printf("t1 : %d\n", t1);
printf("t2 : %d\n\n", t2);
*u = f(&u, &t2);
printf("t1 : %d\n", t1);
printf("t2 : %d\n\n", t2);
printf("u : %d\n\n", *u);
return 0;
}
int f(int** p, int* e){
*p = e;
return 24;
}
You will get
t1 : 0 t2 : 1 t1 : 36 t2 : 1 t1 : 24 t2 : 1 u : 1
Hey, its not any ABNORMAL behaviors, the compiler works correctly.
*u = f(&u, &t2);
int f(int** p, int* e)
{
*p = e; // It means value of t2 gets copied into memory location pointed by u i.e t1
return 24; // Now this 24 would get stored/overwrite in memory location pointed by u i.e t1
} // Thus no change occurs in t2
Remember function " f " only makes changes on VALUE AT MEMORY LOCATION POINTED BY U and not address pointed by u.
精彩评论