6

What are the differences between static and external variables? What are the advantages of making a static variable? Why do we prefer making external variables in multifunction programs? The book says that else it gets initialized very late. I don't get it.

Narfanator
  • 5,595
  • 3
  • 39
  • 71
  • 4
    C# and C++ are very different languages. Since the concept of "external" variables doesn't exist in C#, I'm assuming this is about C++. – Adam Robinson Jul 01 '10 at 19:33
  • 2
    Which book are you referring too? It would be handy to know the name/ISBN to clear up your question (page would also be handy). – Kris van der Mast Jul 01 '10 at 19:34
  • let us c by yashwant kanetkar and turbo c by robert lafore –  Jul 01 '10 at 19:36
  • In addition to Adam's comment, while there are a number of similarities between statics in C# and C++ there are also many differences. Given the scope of these differences you might want to make your question more specific. Do you want to know the differences between the C# and C++ concepts or are you just focused on the difference between static and external in C++? – Chris Taylor Jul 01 '10 at 19:36
  • 3
    Retagged, since both books you mention are C, not C++ or C#. Important distinction. – Adam Shiemke Jul 01 '10 at 19:40
  • really sorry i tagged C# thinking its C –  Jul 01 '10 at 19:45
  • 3
    See [here](http://stackoverflow.com/questions/496448/how-to-correctly-use-the-extern-keword-in-c) and [here](http://stackoverflow.com/questions/534735/internal-static-variables-in-c-would-you-use-them) - unfortunately you have thrown the two keywords together in one question, otherwise i'd be voting to close as a duplicate. – Georg Fritzsche Jul 01 '10 at 19:50
  • @^ i am an ameature and aint get anything from that –  Jul 01 '10 at 19:55

2 Answers2

28

Problem is that in C static can have different meanings. I will try to give an overview of the different situations in the following paragraphs.

If a variable is defined outside a function, it can be used by all functions in the file. Sometimes also called 'global variable'. This means that there is only one instance of this variable for the whole file. Also the name of the variable is stored in the resulting .OBJ file. This latter is important, since if another file also defines a variable with the same name outside a function, the linker assumes that it's the same variable in both cases, and merges them. To make this extra clear, it's best to add the keyword "extern" to one of the variables. In this case, we say that we declare the variable, instead of defining it. It is an extra signal for the compiler/linker to indicate that we actually want to refer to a global variable defined somewhere else.

If you want to define a global variable, but don't want to make it available to other files, add the keyword static before. The keyword static tells the compiler that the variable name must not be stored in the .OBJ file. This means that two .C files with the following line:

static long MyGlobalVariable;

will each have their own variable. Both variables will be called MyGlobalVariable.

If you define a variable inside a function, it becomes a local variable. It comes into existence if the function is called, and disappears again after the function is finished. In some situations you want to keep the value of the variable in between function calls. You could do this by using a global variable (instead of a local variable) but then the variable becomes available for all functions in the file, which you don't necessarily want. In that case you can put the keyword static before the variable, like this:

void MyFunction()
{
static long MyLocalVariable = 0;
++MyLocalVariable;
}

The first time the function is called, MyLocalVariable will be 'created' and initialized with the value 0. At the end of the function, the variable is not destroyed, but kept. So the next time you call this function, the value of the variable will be 1, not zero.

In C it really doesn't matter whether you put the variable outside the function (as global variable) or define it as static inside the function. The only difference is where the variable can be accessed.

In C++, things are quite different. If you write this (outside a function):

MyClass MyGlobalVariable;

MyGlobalVariable will be constructed (this is: the constructor will be executed) at the start of the application, before even main is called. However, you don't have real control over the order in which all global variables are constructed. So if another file contains this:

MyOtherClass MySecondGlobalVariable;

You can't know for sure whether MyGlobalVariable or MySecondGlobalVariable is constructed first. This can give problems if the constructor of one of them relies on the presence (construction) of the other one.

On the other hand, if you define the variable as static inside a function:

void MyFunction()
{
static MyClass MyStaticVariable;
}

Then MyStaticVariable will be constructed the first time the function is called. With this construction, you can write something like this:

MyClass &getMyClass()
{
static MyClass MySelf;
return MySelf;
}

And we have implemented a singleton where we have control on when it is constructed. The first time we need it, it's constructed.

To be honest, this approach is a rather simplistic one, because it may lead to problems in multi-threaded applications. In that case, there are other tricks.

Patrick
  • 23,217
  • 12
  • 67
  • 130
  • The question is only tagged C now. – Georg Fritzsche Jul 01 '10 at 19:58
  • About the example you gave,if i am restarting the program the first line is static long MyLocalVariable = 0; which makes its value 0.When was its value 1 then? –  Jul 01 '10 at 20:24
  • After the line ++MyLocalVariable, its value will be 1. If we re-enter the function later, the value will still be 1, and after the line ++MyLocalVariable, the value will then be 2. And so on. It's important to see that the initialization to zero is only performed the first time the function is entered (or more precisely, the moment the variable is 'constructed'). – Patrick Jul 01 '10 at 20:47
-3

"Static" more or less means "this will always exist". Depending on the context, you get different results:

 static int global_variable;
 void function()
 {
      static int global_function_variable;
 }

 class foo
 {
      static void function()
      {
           static int foo_function_variable;
           //...
      }
      static int foo_variable;
 }

global_variable - Only ever visible within the "translation unit". (Since headers are more or less copied in, does this mean a static global in a header exists as separate variables for all cpp files it's included in?)

global_function_variable is created the first time function is called, and will continue to exist throughout the program's lifetime. The value persists, so if you change it in one function call, the next function call will use the changed variable.

foo::function() is a function that can be called like a global function; you don't need to have an instance of foo to call it. This means it doesn't have a valid this pointer, however. Similarly, foo_variable exists even when there aren't any foo objects. All foo objects have the same foo_variable - if you change it in one object, all other objects "see" the change.

foo_function_variable behaves, I think, just like global_function_variable.

The basic idea behind extern is to control the linkage of a variable: From MSDN :

// specifying_linkage1.cpp
int i = 1;
void other();

int main() {
   // Reference to i, defined above:
   extern int i;
}

void other() {
   // Address of global i assigned to pointer variable:
   static int *external_i = &i;

   // i will be redefined; global i no longer visible:
   // int i = 16;
}

extern int global_variable;

extern can also be used to link a variable using another language, most commonly, C.

global_variable is the most common usage of extern; it says that elsewhere, there's a variable called "global_variable", and we're going to be using that variable. Somewhere, you need to declare the variable without the extern keyword, or it is never actually created.

Narfanator
  • 5,595
  • 3
  • 39
  • 71