0

So, assuming you have a reason for using a goto... just to avoid the inevitable arguments about why they should/shouldn't be used.

What happens when you declare a variable mid function, say a pointer to some memory that has to be free'd, and the flow control jumps past the variable altogether?

int foo(char* bar)
{
    if (NULL == bar)
    {
        printf("ERR1\n");
        goto out;
    }

    char* late = malloc(10 * (*bar));
    if (NULL == late)
    {
        printf("ERR2\n");
        goto out;
    }

    // More logic here
    if (1)
    {
        printf("ERR3\n");
        goto out;
    }

    // etc

out:
    free(late);
    return 0;
}

There are cases where in 'out:', you definitely want to free the memory allocated to variable 'late'(eg it fell through or came from 'ERR3'). There are also cases early in the function where late hasn't even been created yet and you jump past them.

Normally, when you declare a local variable like this, in assembly, there are some stack operations to move the stack pointer to have space to hold the new variable. I'd expect goto to act like an unconditional branch operation to a label. At the end of the function, all the locals gets left on the stack as the stack pointer is adjusted so control can return to the caller.

So, what happens with the 'late' variable when we hit 'ERR1'? Is space for it ever created on the stack? How does the 'free' call work just after the 'out' label?

LawfulEvil
  • 2,267
  • 24
  • 46
  • late is uninitialized. The call to free will cause undefined behavior. – 2501 Nov 02 '16 at 11:47
  • Thx, I found the duplicate but wasn't sure if it was just initialization or declaration that caused problems. – LawfulEvil Nov 02 '16 at 12:12
  • 1
    Just initialization, the lifetime of late is the entire function. You could define and initialize it to NULL before any call to goto at the top of the function. Then the behavior would be defined. – 2501 Nov 02 '16 at 12:15
  • There will be space for the 'late' variable because it is in scope. It may or may not be on the stack. The compiler may decide to keep it in a register. – Ian Abbott Nov 02 '16 at 13:51

0 Answers0