Take the 2-minute tour ×

To me, the use of the keyword static in C and languages like C# and Java are "false friends" like "to become" in English and "bekommen" in German (= "to get" in English), because they mean different things.

In C static means, that the function or variable is only accessible via functions inside the same source file, comparable to private functions and members in C++, Java and C#.

In C++, Java and C# static means, that the methods are not members of a class instance, but effectively are more or less like C functions plus namespace.

IMHO these two concepts are quite different, so why did the designers of C++ and later Java and C# choose the static keyword for that behaviour? Is there a logical connection that I miss?

EDIT I know, that static in C does not govern accessability in a way similar to private in C++, but can be used in that way, see http://stackoverflow.com/a/1479639/124983

share|improve this question
add comment

5 Answers

up vote 5 down vote accepted

I have a book about the design of C++ by Bjarne Stroustrup (the inventor of C++). I don't have it right here so I can't lookup the exact quote right now, but in it he admits that when he added static to C++, he didn't fully understand what it meant in C. So that's why in C++ it has a different meaning than in C.

Java and C# inherited the meaning from C++.

share|improve this answer
add comment

Notably, C++ has both uses of static, and I think there's a third somewhere.

Generally, I think that the C use of static does not correspond at all to any English usage of the word, whereas I think that static as a static member variable, for example, makes a lot more sense.

Remember that as a language designer, you have a fair incentive to introduce fewer keywords into the language, to disallow less code- especially when you're trying to be source-compatible with C, as in C++, and the static keyword already existed, so they couldn't break any C programs trying to compile as C++ by re-using it.

Edit: I knew there was a third. C has function-level static variables. The static member is just a scoped version of this functionality. Therefore, both uses of static originate from C.

share|improve this answer
c has two uses of static (linkage and lifetime), c++ has both these and the class one –  jk. Mar 28 '12 at 10:56
@jk: The class version is the same thing as the function-level static, it's just scoped to a class instead of a function. –  DeadMG Mar 28 '12 at 13:33
@jk. Many think of static having three uses in C (function scope variable, compilation unit scope for variables, compilation unit scope for functions). It really is doing the two same things in these three cases (linkage and lifetime), I share your opinion on this. The view of three uses of static in C is more common, sadly. It helps people understand how to use it, but not how it really works. –  Gauthier Mar 28 '12 at 14:07
You're forgetting the new C99 usage of static: stackoverflow.com/questions/3430315/… –  Austin Mar 31 '12 at 7:37
add comment

In C++, static has the following four uses:

  • Global (file-level) function and variable declarations: with static, you are specifying internal linkage. That means that the symbol is only used in that one compilation unit (.cpp/cc/whatever file, not a header). This is what you are referring to as "private".

  • Local variables: Static storage duration specifies that the variable should retain its value between function calls.

  • Data members: Static data members are shared between the instances of the class (i.e. there is only one copy of the member). This is akin to C# and Java static.

  • Member functions: Static member functions are member functions that don't have an implicit this pointer; they can be invoked without an instance. This is also much like in C# or Java.

So, as you can see, they dropped two of the above meanings. For scoping it is quite understandable why: both C# and Java (and even C++) relies on namespaces to do that. C++ probably has the internal linkage feature for backwards compatibility. Ditching static local variables is probably two-folded: for once, it can be difficult to fully understand its consequences, and these languages aim for simplicity. Second, both Java and C# has a garbage collector which (I can imagine) causes difficulties to implement such behavior.

share|improve this answer
"C++ probably has the internal linkage feature for backwards compatibility." - one might add (IIRC) that the C++ Standard first deprecated this use of static (preferring anonymous namespaces) and then, in its current incarnation C++11 de-deprecated the use of static for this. (all IIRC) –  Martin Ba Mar 28 '12 at 17:27
Really? I'm pretty sure that compilers didn't honor this deprecation then, because it worked with at least two mainstream ones (gcc and MSVC). –  Tamás Szelei Mar 28 '12 at 17:48
No compiler threw it out as far as I know. Still I think the '98/'03 standard deprecated it or somesuch. What I actually wanted to say with my comment was that the internal linkage thing is a feature that is apparently also considered useful in C++, so it's not only there for backwards compatibility. –  Martin Ba Mar 28 '12 at 18:28
The "c++-y" way of doing the same thing is to declare in an anonymous namespace. –  Tamás Szelei Mar 28 '12 at 19:16
"is to declare in an anonymous namespace" - except that it is not the same thing technically. (I do apologize for not having more references, but I lack the time atm. to look it up. (I think it was mentioned in the comp.lang.c++.moderated NG, and maybe one can find some reference in the standard papers of WG21 ...) –  Martin Ba Mar 29 '12 at 5:49
add comment

C++ took it from C, because C++ likes to reuse existing keywords instead of introducing new ones, to minimize breaking existing code.

Java and C# then took it from C++.

share|improve this answer
add comment

C static does not govern accessibility, and isn't analagous to private in the way you suggest.

At file scope, it governs availability of the name (linker symbol), not the thing - you can pass a pointer to a static function or global from the translation unit where it is defined to code in another file, and it will work fine.

The C++ way of doing this (as DeadMG says, the C way is still available too) is to use an anonymous namespace.

In function scope, it essentially replaces the local variable with a global which is only accessible (by name again!) inside that function - this is identical in C++ (so, there isn't a more C++y way of doing it).

As for why C++ used the static qualifier for class members; it's probably right to say that this is to minimize the number of new keywords introduced. (Note the recent re-use of auto for comparison).

Calling per-class data static (so implicitly per-instance data are dynamic) seems fairly intuitive to me, but since I don't remember the process of forming that intuition, I can't really comment objectively on whether it made sense when starting out.

share|improve this answer
add comment

Your Answer


