clazy-evaluationoperator-precedenceevaluation-strategy

Evaluation Order for Dummies


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.

}


Solution

  • 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.