0

I can't understand evaluation strategy no matter how much I read the topics. Can you explain the three evaluation orders to me with an example? I am writing a code below. Can you explain call by need(lazy evaluation), call by name (normal order evaluation), call by reference using the code below. You can also explain them with your example too. All I want is to understand them, but I just can't understand.

int a[4] = {10,20,30,40};
int i = 0;
int *p;
void test(int x, int y, int z)
{
    p = (int *)malloc(sizeof(int));
    *p=x;
    x++; y++; z++;
    p = &z;
    printf("%d %d %d\n",x,y,z);
    x++; y++; z++;
    p = &z;
    printf("%d %d %d\n",x,y,z);
}
main()
{
    test(i,a[0],a[i]);
    printf("%d %d %d %d %d\n", a[0],a[1],a[2],a[3],*p);
}

Thanks in advance.

}

Liath
  • 9,913
  • 9
  • 51
  • 81
jason
  • 6,962
  • 36
  • 117
  • 198
  • I think these concepts have no power in the C language, where evaluation is always "normal", and evaluation order issues only arise for statements with side-effects. The closest I see is the difference between function calls by value or by reference/pointer. ...On the other hand, if all you want is a detailed explanation of each line of your code, that I can do. – Medinoc Jun 18 '13 at 13:22

1 Answers1

1

There is no laziness here because everything affected is passed by value, and the global pointer is never dereferenced until it's undefined behavior to do so (pointer to a local variable of a function that has already returned).

Program behavior, with the values of appropriate expressions as they would appear on a debugger's watch list. Note that *p is an expression, not a variable: A debugger would evaluate it lazily, but it's not something really in memory.

  1. Call to test() evaluates the expressions i, a[0] and a[i] to 0, 10 and 10 respectively.
  2. test(0, 10, 10) begins --> {x, y, z, p, *p} = {0, 10, 10, (uninitialized), (invalid)}
  3. p = (int *)malloc(sizeof(int)); --> {x, y, z, p, *p} = {0, 10, 10, (somewhere on heap), (uninitialized)}
  4. *p=x; --> {x, y, z, p, *p} = {0, 10, 10, (somewhere on heap), 0}
  5. x++; y++; z++; --> {x, y, z, p, *p} = {1, 11, 11, (somewhere on heap), 0}
  6. p = &z; --> {x, y, z, p, *p} = {1, 11, 11, &z, 11} (memory leak, address of malloc'd memory is "forgotten" without being freed)
  7. printf("%d %d %d\n",x,y,z); displays 1 11 11
  8. x++; y++; z++; --> {x, y, z, p, *p} = {2, 12, 12, &z, 12}
  9. p = &z; No change, p was already pointing to z.
  10. printf("%d %d %d\n",x,y,z); displays 2 12 12
  11. Function returns. p is now a dangling pointer! Anything could happen when you dereference it.
  12. The big printf(): The fifth number is undefined (the application could even crash before the function is even called), but it may possibly be 12 if the stars are right. In that case, it displays 10 20 30 40 12

In fact, the pointer is not really used to demonstrate how pointers work here: It's kind of a lot of wasted potential. As far as pointers go, this is a bad example code.

Medinoc
  • 6,577
  • 20
  • 42