Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is accessing a static out of scope undefined behavior?

While speaking with a colleague of mine, they said that:

foo() {
    int *p;
    {
        int x = 5;
        p = &x;
    }
    int y = *p;
}

creates undefined behavior because lifetime rules and scope rules do not specify.

However:

foo() {
    int *p;
    {
        static int x = 5;
        p = &x;
    }
    int y = *p;
}

is not undefined! You end up with "indirect scoping" issues.

The use of terminology does not sound correct.
I know that static has nothing to do with scoping.
Is it true that the second case has defined behavior?

like image 560
Trevor Hickey Avatar asked Jun 13 '16 17:06

Trevor Hickey


People also ask

Do static variables go out of scope?

Static variables offer some of the benefit of global variables (they don't get destroyed until the end of the program) while limiting their visibility to block scope. This makes them safer for use even if you change their values regularly.

What is Undefined Behavior in programming?

In computer programming, undefined behavior (UB) is the result of executing a program whose behavior is prescribed to be unpredictable, in the language specification to which the computer code adheres.

What type of behavior C is undefined?

According to the C standards, signed integer overflow is undefined behaviour too. A few compilers may trap the overflow condition when compiled with some trap handling options, while a few compilers simply ignore the overflow conditions (assuming that the overflow will never happen) and generate the code accordingly.

Does Java have Undefined Behavior?

Java is thus two steps removed from Modern C's model of "Undefined Behavior"; it rigidly prescribes many more behaviors, and even in cases where behaviors are not rigidly defined implementations are still limited to choosing from among various possibilities.


2 Answers

Yes the second case has well defined behavior. A static variable is basically a global variable whose name is scoped to the scope it is declared in. It is initialized the first time the scope is entered and then it lives on for the life of the program.

So when we reach

int y = *p;

p points to a variable that you can no longer reach (can't get back to that code) but still has a valid lifetime.

To quote the standard [basic.stc.static]

All variables which do not have dynamic storage duration, do not have thread storage duration, and are not local have static storage duration. The storage for these entities shall last for the duration of the program

emphasis mine

The first case is undefined as the lifetime of the local scope x ends at the } and trying to refer to it after its lifetime ends is undefined behavior.

like image 199
NathanOliver Avatar answered Oct 23 '22 09:10

NathanOliver


quoting from here

The static storage class instructs the compiler to keep a local variable in existence during the life-time of the program instead of creating and destroying it each time it comes into and goes out of scope. Therefore, making local variables static allows them to maintain their values between function calls.

so yes in the second case x is in existence during the complete life-time of the program.

hence has defined behavior.

like image 38
mssirvi Avatar answered Oct 23 '22 08:10

mssirvi