static in C and C++

| 分类 C++  | 标签 C++_keywords 

The static variable is located at the .data segment while the normal variable is located at the stack segment when the process is running. So the memory of static variable always exits even we are outside the scope. So if you declare a static variable inside a function, you can still access it even you are outside the function.

The static keyword also means that variable is limited in the current source file. So when you compile an object with multiple source files this can help reduce the multiple definition of the variables with the same name.

Don’t use static variable in the header file. If you do so, you will find that every compiler unit(the executable object) will contain a copy of that static variable in the .bss or .data section. This is a waste of memory and it doesn’t make sense. If you link these objects together into a program file, you will find that there are muliple copies of that static variables and one copy for each involved objects in the .bss or .data section. In stead of using the static variable, we should use the extern keyword to declare the variable and then initialize it once at one cpp file. As the following code shows:

// The header file A.h

#ifndef A_INCLUDED
#define A_INCLUDED

/* If you don't use the extern keyword,
 * you will get an error that indicating
 * redefinition of ‘std::string name. */

extern string name;
#endif
// The source file A.cpp

#include "A.h"

string name = "Joey";
// The source file main.cpp

#include "A.h"

int main(int argc, char* argv[]) {
    extern string name;
    return 0;
}

Then you will find that name variable is located at the .bss section of the compiler unit. Any other compiler unit that include the involved header file will not have a copy of that global variable and the final output program file has only one memory location for name.

$ objdump -t A.o | grep name
0000000000000000 g     O .bss   0000000000000020 _Z4nameB5cxx11

$ objdump -t temp.o | grep name
0000000000000000         *UND*  0000000000000000 _Z4nameB5cxx11

$ objdump -t a.out | grep name
0000000000008160 g     O .bss   0000000000000020              _Z4nameB5cxx11

Note that you can’t initialize the global variable name in the head file, too. If you do so, you will get a link error that multiple definition of name. Since any other compiler unit like main.o in my example that includes the header file A.h will contain a copy of the global variable name.

It is the same for the static function. We should not declare the static function in the header file or you will get a copy for each compiler unit in the .text section. You can only declare static function in the source file.

It seems that we must initialize the static variable with constant, or we will get an error when we compile the grogram as this post says. However, I try myself with gcc and it seems now things are different. As the following code shows:

#include <stdio.h>

static int myNum;
static int myNumInit = 100;

int main(int argc, char* argv[]) {
    printf("myNum is %d and myNumInit is %d\n", myNum, myNumInit);
    return 0;
}

I can successfully compile the above code and the result of myNum is 0. I take a look at the symbols of the program with the command objdump -t a.out | grep "myNum". I find out that myNum is locatead at the .bss section and myNumInit is located at the .data section. Now I will try to explain why this happen in my opinion. For myNum, it is 0 because uninitialized variables in .bss section of a program will be initialized as 0 when they are loaded in the memory of the .bss segment of the process, which involved the program. For myNumInit, we explicitly initialze it with 100 so that it is stored at the .data section of the program.

So I think the static variable must be initilaized. If the programmer don’t initialize it, the compiler will initialize it as 0.

static in C

Note that using the inline keyword in C with a function should be used with the static keyword or extern keyword. Otherwise you will get a link error that no undefined reference to that function.

static in C++

The main difference of the useage of static keyword between C and C++ is that C++ can use it with the class.

When a class member variable is declared as static, it means that there is only one memory location for that variable for all the instace objects of that class. You should initialize that variable outside the class declaration with the the class name and scope resolution operator.

For static member function, it is only allowed to access the static member variable or other static member function and it can’t access other non-static member variable or non-static member function.


上一篇     下一篇