Pointer and proper expression evaluation in C

I have a question in C. Consider 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 side of the expression (i.e. * u):

 *u = f(&u, &t2); 

fixed before processing the function f. In fact, I was expecting the following result, since the function f changes the pointer u:

 t1 : 0 t2 : 1 t1 : 36 t2 : 1 t1 : 36 t2 : 24 

This is normal? Am I missing something in my class C?

+4
source share
4 answers

There is no sequence point in the assignment expression, and there is no guaranteed evaluation order between the left and right operands of the assignment expression. The code you wrote does not have clearly defined behavior in C, so the behavior you see does not mean that your compiler does not match.

6.5 / 3:

Except as noted below (for call functions () , && , || , ?: And comma operators), the order in which subexpressions are evaluated and the order in which side effects occur 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 evaluating *u .

+5
source

After running the code, I got the answer you expected. You should carefully check your code.

Edit: after reading another answer, I felt that I had to publish my specifications. I am running Visual Studio 2010 64 bit, in Windows 7 Ultimate 64 bit.

0
source

When the function is called, the memory location where the return value will be stored is fixed. Although you are changing what u points to, the assignments (memory location) that will occur in the function call have already been 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'll get

  t1: 0
 t2: 1

 t1: 36
 t2: 1

 t1: 24
 t2: 1

 u: 1
0
source

Hey, its not any ABNORMAL behavior, the compiler is working 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 ie t1 return 24; // Now this 24 would get stored/overwrite in memory location pointed by u ie t1 } // Thus no change occurs in t2 

Remember that the "f" function only makes changes for VALUE AT MEMORY POSITION, DOT AT U, and not the address indicated by u.

0
source

Source: https://habr.com/ru/post/1339787/


All Articles