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.

Community
  • 1
  • 1
Hristo
  • 45,559
  • 65
  • 163
  • 230
  • 2
    But "the previous question" is about Java... – kennytm Aug 05 '10 at 16:07
  • 4
    Depends on which usage of static you're talking about. One of my favorite quotes. "It's not a new version of C++ until they find a new use for static" – JaredPar Aug 05 '10 at 16:07
  • @Kenny... yes I know. That is why I want to expand the scope to consider C/C++. I got the answer with Java and I'm wondering if that differs when dealing with C/C++. – Hristo Aug 05 '10 at 16:09
  • @JaredPar... I'm not too sure which usage I'm talking about. Could you perhaps make an answer specifying the different types of usage, advantages/disadvantages of each, etc...? – Hristo Aug 05 '10 at 16:10
  • Note, although one of the answers claims this is deprecated, [this is not currently the case](http://stackoverflow.com/a/34140653/1708801) ... although it was pre C++11. – Shafik Yaghmour Dec 07 '15 at 20:16

6 Answers6

13

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;    
}
  • 1. What is a translation unit? 2. How does this idea work when dealing with classes? – Hristo Aug 05 '10 at 16:11
  • 2
    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 Aug 05 '10 at 16:12
  • @Hristo Classes cannot be static, but instances of them can be. –  Aug 05 '10 at 16:14
  • 1
    @Hristo: A translation unit designates a cpp file. That's compiler jargon. – Philippe A. Aug 05 '10 at 16:29
  • @Philippe... thanks. How important do you think it is for me to know such "compiler jargon"? – Hristo Aug 05 '10 at 16:40
  • 1
    @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. –  Aug 05 '10 at 16:51
  • 3
    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 Aug 05 '10 at 17:09
  • BTW, this is only one of the meanings of `static`, there are other meanings in other contexts. – David Rodríguez - dribeas Aug 05 '10 at 17:34
  • @David This answer was to the original question about "global" variables. –  Aug 05 '10 at 17:41
  • "The use of static (in regards to keeping a free function or a global variable bound to the translation unit), is in fact depreciated in the current C++ standard." Is it really depreciated, or just discouraged? – Trevor Hickey Dec 07 '15 at 17:41
  • Note, this is [no longer deprecated](http://stackoverflow.com/a/34140653/1708801) – Shafik Yaghmour Dec 07 '15 at 20:19
  • @TrevorHickey note, the user is greyed out, so the account is deleted. – Shafik Yaghmour Dec 07 '15 at 20:19
10

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
  • 204,818
  • 23
  • 294
  • 489
6

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
  • 5,684
  • 21
  • 25
  • 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 Aug 05 '10 at 16:42
  • 1
    @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 Aug 05 '10 at 17:40
  • @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 Aug 05 '10 at 17:45
2

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.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • .. 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 Aug 05 '10 at 16:19
  • @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. – Puppy Aug 05 '10 at 16:24
  • I'll agree that C use of static should be approached carefully, but it can be useful in embedded systems development. – Throwback1986 Aug 05 '10 at 17:00
  • 1
    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 Aug 05 '10 at 17:15
1

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
  • 27,972
  • 12
  • 65
  • 103
0

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).

josh
  • 13,793
  • 12
  • 49
  • 58
  • 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 Aug 05 '10 at 16:43
  • 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 Aug 05 '10 at 17:11