A Query Regarding The Static Storage Class Modifier

closed account (zb0S216C)
Static objects with no linkage are found within a local scope, such as a function body. Since functions can be called again, and again, the static object can be used each time the function is invoked. That said, what if a static object was declared within a local scope, but not within a function body? For example:

1
2
3
4
5
6
7
8
9
10
11
12
void Function( )
{
    static int object( 0 ); // No linkage.
}

int main( )
{
    // Anonymous scope:
    {
        static int object_two( 0 ); // No linkage.
    }
}

In the code above, the anonymous scope contains a static object. Since the scope is entered only once, what happens to object_two? Does it remain a static object with no linkage? Or does the compiler see this and ignore the static keyword to reduce the amount of memory allocated to store static objects?

Wazzak
Last edited on
if a local object is not accessed the compiler certainly will remove it no matter if you declare it static or not.
I think you are messing two categories storage duration and linkage. Static storage duration means that memory will be allocated for an object before program execution,
> Or does the compiler see this and ignore the static keyword to reduce the amount of memory allocated to store static objects?

The compiler can optimize away any object altogether, as long as the observable behaviour of the program does not change. In the example, both that static int objects will be optimised away as if the program was
1
2
void Function( ) {}
int main() {}

... conforming implementations are required to emulate (only) the observable behavior of the abstract machine ... - IS

The code that is generated for:
1
2
3
4
5
6
7
8
9
10
int function( char c )
{
    int a = c + 5 ;
    ++a ; // a == c+6
    ++a ; // a == c+7
    int b = a - c ; // b == 7
    if( b < 2 ) // b < 2 == false
       std::cout << "b is less than 2\n" ; // dead code
    return b - 5 ; // b - 5 == 7 - 5 == 2 => return 2 ;
}

is:
1
2
3
__Z8functionc:
	movl	$2, %eax
	ret


However, if the initialization or de-initialisation of an unused static variable has "side effects" - some effect that is observable, it can not be optimized away. For example,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
struct A
{
    char cstr[100] ;
    #ifdef HAS_SIDE_EFFECTS
        A() { std::cout << "A::constructor\n" ; }
        ~A() { std::cout << "A::destructor\n" ; }
    #endif // HAS_SIDE_EFFECTS
};

void foobar( int a )
{
    if( a > 1 )
    {
        static A static_object ;
    }
}

int main( int argc, char* argv[] )
{
   foobar( argc ) ;
}


The code generated for foobar is just a single ret instruction if HAS_SIDE_EFFECTS is not defined. Compile with -D HAS_SIDE_EFFECTS and the static object can't be optimized away.

Note: There are a few places where the IS allows optimisations "even if there are side effects" - for example in copy-elision.
Last edited on
closed account (zb0S216C)
coder777 wrote:
if a local object is not accessed the compiler certainly will remove it no matter if you declare it static or not.

That makes sense. One thing though: Since the amount of static objects cannot change during run-time, and with the static object not on the stack, how can the compiler remove it?

vlad from moscow wrote:
Static storage duration means that memory will be allocated for an object before program execution,

I know that. static objects aren't stored on the stack, but within a pre-allocated region of memory where all static objects reside.

Edit: I didn't see JLBorges post.

OK, so let me get this straight. If a static object isn't modified, or even referenced during run-time, the object is optimised away?

Wazzak
Last edited on
> If a static object isn't modified, or even referenced during run-time, the object is optimised away?

Not necessarily. If either the initialization or the deinitialization of the object has an observable side effect, it cannot be optimised away.

Modify your orginal example to:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <cstdlib>

void Function( )
{
    static int object( ( (std::cout << "hello world\n"), 0 ) )  ; // No linkage.
}

int main( )
{
    // Anonymous scope:
    {
        static int object_two( ( std::srand(9), 0 ) ); // No linkage.
    }
}

and neither object in Function() nor object_two in main() can be optimized away.



> the object is optimised away?

At best, all we would be able to say is: 'this object can be optimised away'. Whether it is actually optimised away or not is a quality of implementation issue.
Last edited on
closed account (zb0S216C)
I understand now.

Thanks for all your help, JLBorges, and you too, Coder777 :)

Wazzak
Topic archived. No new replies allowed.