views:

321

answers:

6

This is an expansion of the scope of a previous question of mine.

What exactly is "static", how is it used, and what is the purpose of using "static" when dealing with C++?

Thanks.

+14  A: 

It means that the variable is local to a translation unit (simply put, to a single source file), and cannot be accessed from outside it. This use of static is in fact deprecated in the current C++ Standard - instead you are supposed to use anonymous namespaces:

static int x = 0;    

should be:

namespace {
    int x = 0;    
}
anon
1. What is a translation unit? 2. How does this idea work when dealing with classes?
Hristo
The question is also tagged C, where this is still the way to do things.
Jens Gustedt
The anonymous-namespace thing really needs to be beaten into people's heads. There are too many C++ programmers who learned C++ 15 years ago and haven't bothered to learn anything since then.
Kristopher Johnson
@Hristo Classes cannot be static, but instances of them can be.
anon
@Neil... Thanks!
Hristo
@Hristo: A translation unit designates a cpp file. That's compiler jargon.
Philippe A.
@Philippe... thanks. How important do you think it is for me to know such "compiler jargon"?
Hristo
@Hristo If you do need to know it, get it from an authoritative source - a translation unit is not necessarily a .cpp file. That's why I had "simply put" when I explained the term in my answer.
anon
From the standard 2[lex]/1: "The text of the program is kept in units called source files in this International Standard. A source file together with all the headers (17.4.1.2) and source files included (16.2) via the preprocessing directive#include, less any source lines skipped by any of the conditional inclusion (16.1) preprocessing directives, is called a translation unit." (ie. the result of the input code after preprocessing) The important bit is that if you declare a `static` in a header it will be a different var in each translation unit including it.
David Rodríguez - dribeas
BTW, this is only one of the meanings of `static`, there are other meanings in other contexts.
David Rodríguez - dribeas
@David This answer was to the original question about "global" variables.
anon
+2  A: 

Static basically means that a variable is tied to the lifetime of the program and not of any given function or class instance. When should you use it? Don't. What is the purpose? Debugging data, mostly.

Generally, in C++, if you find yourself using static data, you've done it wrong. There are times when it's appropriate, but they're very rare.

DeadMG
@DeadMG... haha :) Don't use static. Easy enough to remember. What do you have to say about Neil's answer? Also, is your advice valid for C as well?
Hristo
@Hristo: Yes. Also, Neil's answer isn't wrong. For it's purpose, static has been superseded. That doesn't mean that it served a useful purpose to begin with. It's the kind of thing where, there are some things that are pretty impossible without static. But, it can be very overused by new programmers and should be avoided whenever possible, and those things which it is truly necessary for are quite rare.
DeadMG
Thanks for the clarification.
Hristo
I'll agree that C use of static should be approached carefully, but it can be useful in embedded systems development.
Throwback1986
What about `int x; int main() {}`. `x` is not `static` and its lifetime is bound to the lifetime of the program. The keyword `static` is used with different meanings in different places
David Rodríguez - dribeas
+6  A: 

This stuff seems to be fairly well covered here.

But to paraphrase, there are 2 uses in C

  1. Prevent the use of a global variable outside the scope of the file that defines it.
  2. Allow local variables within a function to persist accross invocations of the function, as in

    int getNextId() { static int id = 0; return id++; }

C++ inherits both of these, and adds two uses of its own.

  1. static member variables: Variables that are "shared" accross all instances of a class, and can also be accesses without reference to an instance of the class. Shared seems like the wrong word, but in essence I beleive that the result is that any reference to a static member variable references the same memory location.
  2. static methods: Methods that can be called without reference to a specific instance of the class that defines it.
torak
Nicely structured answer! Thanks for the response and the reference. It seems from your answer that "static" in C++ isn't much different from Java.
Hristo
@Hristo: Java only has the last two cases. The first 1 and 2 use cases (the C part) cannot be used there.
David Rodríguez - dribeas
@David... oh ok. Thanks. btw... I'll read over your official answer when I have a little more time to dedicate the appropriate amount of focus. Thanks for taking the time!
Hristo
+1  A: 

Static class members are data and functions that are associated with the class itself, rather than with the objects of the class.

In the following example, class Fred has a static data member x_ and an instance data member y_. There is only one copy of Fred::x_ regardless of how many Fred objects are created (including no Fred objects), but there is one y_ per Fred object. Thus x_ is said to be associated with the class and y_ is said to be associated with an individual object of the class. Similarly class Fred has a static member function f() and an instance member function g().

class Fred {
    public:
        static void f() throw();                           <-- 1
        void g() throw();                                  <-- 2
    protected:
        static int x_;                                     <-- 3
        int y_;                                            <-- 4
};

(1) Member function associated with the class

(2) Member function associated with an individual object of the class

(3) Data member associated with the class

(4) Data member associated with an individual object of the class

Usage:

When you want to keep tract of the number of instances of a class created you use static variable. For example in a 'Car' class each Car instance may have a unique serial number(_y in this case) and the company may want to keep track of the number of cars produced(_x in this case).

Prabhu Jayaraman
Nicely structured answer! Thanks for the response and the reference. It seems from your answer that "static" in C++ isn't much different from Java.
Hristo
Although this doesn't really answer the original question... This only explains static in the context of classes. Not the global scope.For the global scope, it's treated the exact same as C.
Jonathan Sternberg
+1  A: 

When static is used in a class in C++, it means more or less the same thing that it does in Java. For variables it means that one one instance of the variable exists for all classes and for functions, it means that the function does not implicitly access the this pointer at all.

In C and C++ when static is used for a global variable or function, then it means that the variable may only be referenced in the current C or C++ file. In other words, the compiler must not generate any relocation symbols for the variable or function.

When static is used next to a variable in a local function, it means that the variable does not go out of scope but will retain its value from function-call to function-call. The variable become effectively a global variable that can only be accessed from the given function.

doron
+9  A: 

The keyword static has different meanings in C++, depending on the context.

When declaring a free function or a global variable it means that the function is not to be available outside of this single translation unit:

// test.cpp
static int a = 1;
static void foo() {}

If the result of compiling that translation unit is linked with a different translation unit containing symbols a and foo it will not break the One Definition Rule, as in this particular translation unit a and foo are private symbols. This use has been obsoleted by unnamed namespaces.

// test2.cpp
namespace {
   static int a = 1;
   static void foo() {}
}

When declaring a local variable within a function it means that the lifetime of the variable will extend from the first call to the function to the end of the program, and not only for the duration of the call:

int foo() {
   static int counter = 0;
   return ++counter;
}
int main() {
  for ( int i = 0; i < 10; ++i ) { 
     std::cout << foo() << std::endl;
  }
}

In the previous code, counter is initialized once when foo is called for the first time, but the variable will outlive the function and keep the value across different function calls. The previous code will print "1 2 3 4... 10". If the variable was not declared static then the output would be "1 1 1... 1".

Within a class scope, static means that the member is a member of the class, and not of a particular instance. This use is equivalent to the use in your other question: usage of that particular member is not bound to any specific object.

struct test {
   int x;
   static int y;
};
int test::y;       // need to define it in one translation unit
int main() {
   // test::x = 5; // !error cannot access a non-static member variable
                   // without an instance
   test::y = 5;    // ok
   test t, other;
   t.x = 10;       // ok
   t.y = 15;       // ok, the standard allows calling a static member through
                   // an instance, but this is the same as test::y
}

In this case, the member x is a non-static member attribute, and as such there is a different x for each instance of the class. In the sample program t.x and other.x refer to different integers. On the other hand y is static and thus there is a single instance of test::y in the program. Even if the standard allows to call t.y and other.y both uses refer to the same variable. The same goes with member methods. If they are static they are class-level methods and can be called without an instance, while if they are non-static they are applied to a concrete instance and the a.b or a->b syntax must be used.

This use of static is similar to the use of the same keyword in Java, while the other two are not present in that language. There is one use of the keyword in Java that is not present in C++, and that is the use of static class initializers (a block of code at class level surrounded by static { ... }). In Java that block of code will be executed when the class is loaded and only once. Initialization of static member variables in C++ must be done in the initializer of the variable definition.

David Rodríguez - dribeas