Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is a goto in alloca's function scope valid?

The C standard prohibits a goto into a function scope where a VLA exists.

A VLA and the call to alloca function should have the same result on low level.

(I could be wrong, as I'm just a C, not a low level programmer, but in my imagin that appears to be witty)

So will the following snippet be also undefined behaivng?

int main()
{
    char *p;

    goto label1;

    {
        p = _alloca(1);
label1:
        p = NULL;
    }
}

Ofcourse I cant refference p, but whats about the behaviour?

like image 759
dhein Avatar asked May 23 '14 07:05

dhein


People also ask

Are GOTO labels scoped?

Labels are the only identifiers that have function scope: they can be used (in a goto statement) anywhere in the same function in which they appear.

Should I use Alloca?

alloca() is very useful if you can't use a standard local variable because its size would need to be determined at runtime and you can absolutely guarantee that the pointer you get from alloca() will NEVER be used after this function returns.

What is Alloca?

The alloca() function allocates size bytes of space in the stack frame of the caller. This temporary space is automatically freed when the function that called alloca() returns to its caller.


2 Answers

Actually, the rule 6.8.6.1 states:

  A goto statement is not allowed to jump past any declarations of objects 
  with variably modified types.

In your code, there does not exist an object with variably modified types. alloca does not declare an object (that the compiler has to care of). Thus, there is nothing like a scope for alloca, and no reason for undefined behavior in the sense of rule 6.8.6.1.

EDIT

To elaborate the answer a bit: the "undefinedness" of the behavior in case of VLA is due to the promise of a declaration that an object is "known" within its scope (at language level). In general, a declaration sets a context for code execution. There is no need that it is executed at runtime. However, this is not true in case of VLA: here this promise is implemented partly at runtime, breaking C's static declaration approach. To avoid further conflicts that would lead to a dynamic typing system, rule 6.8.6.1 avoids such conflicts.

In contrast, at language level alloca is simply a function; its call does not constitute any scope. It makes only a promise about its run-time behavior in case it is called. If it isn't called, we do not "expect" anything from a function. Thus, its pure existence does not raise any conflict: both cases (bypassing or non-bypassing) have a well defined semantic.

like image 95
Matthias Avatar answered Oct 06 '22 09:10

Matthias


A VLA and the call to alloca function should have the same result on low level.

There are still a few differences. A VLA object is discarded when the scope where it is declared ends and the memory object allocated by alloca is discarded when the function returns.

This makes a difference because the requirement in c99, 6.8.6.1p1 ("A goto statement shall not jump from outside the scope of an identifier having a variably modified type to inside the scope of that identifier") is concerned by the runtime allocation / deallocation of objects with variably modified type. Here the alloca statement is not executed after goto is performed, so I would not think the goto call would invoke undefined behavior.

like image 33
ouah Avatar answered Oct 06 '22 07:10

ouah