tags:

views:

175

answers:

2

I have a few questions about the static keyword in C++ (and probably with other languages as well.) What is the purpose of declaring a function as static?

void static foo(int aNumber) {
... }

How about a static inline function?

void static inline foo(int aNumber) {
... }

Is there any benefit to using the static keyword with a function, and do those benefits apply to class functions as well? I realize some datatypes like structs and arrays have to be static when compiling with an older compiler, but is there any point when using a new ANSI-C++ compiler (like MS VC++ 2008)? I know that using a static variable inside a loop saves time by keeping the data in memory and not reallocating memory every loop iteration, but how about when a variable is declared only once, like at the top of a header file or within a namespace?

+11  A: 

Depends on Context:

Like many things in C++, static means different things depending on its context.

It's very common in C++ for the same word to mean different things depending on its context.
For example:

  • * is used for multiplication, dereferencing a pointer, and creating pointers.
  • & is used to get the address of variables, to declare a reference, and as a bitwise AND operator.

Global use of static:

If you declare a function or variable as static outside of a class and in global scope, it is specific to only that file. If you try to use that variable or function in a different file (via a forward declaration) you will get a linking error.

Example:

a.cpp:

static void fn()
{
  cout<<"hello a!"<<endl;
}

b.cpp:

void fn();
void gn()
{
  fn();//causes linking error
}

This feature allows you to use a function that no other file will ever see, that way you don't cause possible linker errors of a symbol defined multiple times. The preferred method to do this is with anonymous namespaces though:

a.cpp:

namespace
{
  void fn() // will be static to a.cpp
  {
    cout<<"hello a!"<<endl;
  }
}

Inside of a class use of static:

If you declare a function or variable as static inside of a class (or struct), it is a class function or class variable. This means that there is only one for that whole class. A class function can only use class variables. A class variable is shared amongst all instances of that class.

class C
{
public:
  static void fn()
  {
    y = 4;//<--- compiling error
    // can't access member variable within a static function.
  }

  int y;
}

This is a great feature to use if you have something that is specific to the class of your objects, but not specific to an instance.

Inside a function use of static:

If you declare a variable as static inside of a function, you can consider that the variable value will persist upon calls. It will only be initialized once.

Example:

//Will print 0, then 1, then 2, ...
void persistentPrintX()
{
  static int x = 0;
  cout << x << endl;
  x++;
}

I personally try to avoid this, and you probably should to. It is not good to have global state. It is better to have functions that given the same input guarantees the same output.

Just like in the English language:

The concept of context sensitive meaning is not specific to C++, you can even see it in the English language.

  • I am going to screen a movie (Means showing the movie)
  • The screen on the TV is broken (Means a part of the TV)

Other meanings in other programming languages:

Depending on the programming language there can be a different meaning, but the first thing most people think of when you say static is a class variable/function vs a member variable/function.

Brian R. Bondy
The most confusing use of static ever. Couldn't they have just used `private`.
Yacoby
They could but then they would have an overloaded word: private meaning different things :)
Brian R. Bondy
Reusing keywords sounds indeed silly. That's like using `auto` for different things. Oh, wait...
Frerich Raabe
Dooms101
I think that especially the declaration of pointers and references would have been better another way. Definitely causes confusion to people that are learning.
Brian R. Bondy
Typo: "This means that there is only one for that whole function" in the class function section.
Bill
@Bill: Thanks, fixed.
Brian R. Bondy
Might be worth noting under "Global use of static" that using static to limit something to translation unit scope is deprecated in C++ in favor of anonymous namespaces.
Dan Olson
@Dan: agreed, added.
Brian R. Bondy
Well documented! the multiple, completely unrelated and linguistically confusing meanings of "static" is one of my (several) pet peeves about C/C++... (Why does "static" on a global variable mean file-scope? Why not "file" or "local"? *sigh* there's nothing more static about that than any other global variable...)
Brian Postow
@stusmith: Thanks, nice add.
Brian R. Bondy
+3  A: 

I hang around on the ##c++ irc channel on irc.freenode.net and I really like the clarification on static that the bot nolyc is programmed to give. I quote word for word:

When used inside a function, the static keyword indicates that a variable is shared between all calls of the function. When used inside a class, it indicates that the variable or function is a member but is not tied to a specific instance. When used inside a namespace, it specifies internal linkage.

I hope that clears things up. I haven't answered all your questions. I would say that you should use the static keyword to do what it was intended to do. Use it as a tool to accompolish your task, if it is the right one for the job. As far as benefits go, I wouldn't worry. If you need to optimize, then think about those effects if there is no other resort.

I hope this helps.

batbrat