17
$\begingroup$

Across languages that use the word static as a keyword or reserved word, I have observed it to mean:

  • "This variable, despite being declared locally, shall be initialized ahead of time and survive past the end of the function; future calls will use the previous value"

  • "This top-level function or data, although it is global within the current file, has 'internal linkage'; it shall not be visible as part of the public interface of this 'translation unit' or module"

  • "This function defined inside a class is indeed a function, and not a method; it can (or in some cases must) be looked up from the class itself rather than an instance; no instance is required to call it, as it doesn't use any instance data" (some languages that don't use a static keyword still use similar phrasing to describe the feature, such as the @staticmethod built-in decorator provided by Python)

  • "This data defined inside a class is indeed conceptually part of the class, rather than instances; the value is 'shared'" (in some languages, this happens automatically)

... and possibly other things I've forgotten.

It's hard to understand what these ideas have in common, or how the English word "static" describes them.

What is supposed to be the underlying concept here?

What other keywords could be (or are) used to communicate these ideas more clearly?

$\endgroup$
5
  • 8
    $\begingroup$ The premise that there is a unifying underlying concept here is false, so there isn't really an actual answer to the question. $\endgroup$
    – Michael Homer
    Commented May 21 at 21:54
  • 2
    $\begingroup$ @MichaelHomer I would settle for "why has the same term been used to describe these various things - what's the underlying thought process?". $\endgroup$ Commented May 21 at 21:55
  • 9
    $\begingroup$ A lot of the answer to that is going to be "we already reserved the keyword", I think, and then extension from that point. Perhaps that's enough. $\endgroup$
    – Michael Homer
    Commented May 21 at 21:57
  • 1
    $\begingroup$ static just happened to be an appropriate word to use for whatever concept each language designer was thinking of. Different languages can use the same terms to mean entirely different things. The same language can use the same term to mean entirely different things (e.g. Java uses default for both default methods in interfaces and for the default branch of a switch) $\endgroup$
    – user
    Commented May 21 at 21:57
  • $\begingroup$ I guess I won't bother going to retrocomputing.SE , since answers here look great already and this has been much better received than I expected. But maybe the "What other keywords could be (or are) used to communicate these ideas more clearly?" part should be asked separately? It doesn't look like anyone is touching on it... or is that too subjective for here? $\endgroup$ Commented May 25 at 6:29

7 Answers 7

18
$\begingroup$

Generally, the word "static" doesn't have one consistent meaning, but it usually refers to things which are determined at compile-time, or otherwise things which are determined by inspecting the source code without executing it. In contrast, "dynamic" refers to things which are determined at runtime. For example:

However, this dichotomy relates to when something is done, so it is easier to understand when applied to verbs (e.g. type-checking, binding) rather than nouns (e.g. variables, methods). Suppose we say a variable is static: then something about that variable is determined at compile-time, but what? Different languages might disagree:

  • In C, a static variable is a variable whose storage location is (in principle) fixed at compile-time, such that every use of that variable accesses the same storage. This is in contrast to a normal local variable, for which new storage is allocated each time the function is executed.
  • In Java, static variables (i.e. static fields) are quite different ─ they belong to classes, not functions ─ but likewise, all uses of a static field access the same storage. In contrast, for normal fields new storage is allocated each time an instance is constructed. However, unlike C, static fields in Java probably do not have memory addresses allocated at compile-time, since Java allows classes to be dynamically loaded.
  • In Java, a static method is statically dispatched ─ such a method cannot have multiple implementations, so the singular implementation is known at compile-time to be the one executed when the method is called.

However, because the word "static" has these more specific meanings when applied to different concepts, it has ended up having multiple meanings depending on context, probably because it has been redefined in different ways, and then new languages borrow from different older languages which adopt different definitions.

For example, although Java's notion of "static" can be understood as referring to "compile-time" properties, it is more useful for Java users to define "static" as something belonging to a class rather than to an instance. This is somewhat consistent with the general rule, since classes notionally exist at compile-time but instances are not instantiated until runtime; nonetheless, it is a different definition. Then Python borrows that new definition for its @staticmethod decorator ─ the method belongs to the class, and is invoked without a class instance ─ despite that classes don't notionally "exist at compile-time" in Python (and despite that instance methods are also class members in Python).

It also gets trickier when we consider that "compile-time" vs. "runtime" may be an opaque implementation detail which doesn't match what the specification says, and this distinction is even fuzzier when interpreters invoke bytecode compilers or JITs. For example, Java's specification says that a non-static method invocation is evaluated by locating and executing the appropriate method implementation, based on the object's runtime type (i.e. dynamic dispatch). However, a Java compiler or JIT may be able to determine that a particular instance method call can only refer to one possible implementation, e.g. because it's private or final and therefore can't be overridden, or perhaps because it hasn't been overridden in any subclasses. In that case the compiler might use static dispatch as an optimisation; but of course we wouldn't say that the method is static.

$\endgroup$
3
  • $\begingroup$ I think the commonality between static methods and static variables is that they don't have an instance context. $\endgroup$ Commented May 22 at 21:30
  • 2
    $\begingroup$ @PaŭloEbermann That's what the word "static" means in Java, and in languages which borrow that meaning from Java, and my answer mentions that. But most likely, Java uses the word "static" for this because of its association with static allocation and static dispatch. $\endgroup$
    – kaya3
    Commented May 22 at 22:18
  • $\begingroup$ "it usually refers to things which are determined at compile-time" - this seems like the seed of an idea for clearer names. But I still can't think of any. $\endgroup$ Commented May 25 at 6:34
8
$\begingroup$
  1. "This variable, despite being declared locally, shall be initialized ahead of time and survive past the end of the function; future calls will use the previous value"

The first one is the oldest: it indicates that there should be one predetermined storage location for that variable, and that it shouldn't be "automatically" (stack) allocated for each call. Once upon a time, it was normal for everything to be static, but eventually automatic storage became predominant and so a use appeared for a static keyword.

  1. "This data defined inside a class is indeed conceptually part of the class, rather than instances; the value is 'shared'"

The fourth one is analogous to the first; a class is usually a singleton, so static class data is also in just one place. Where static variables in functions don't get a new copy for each call, static members in classes don't get a new copy for each instance.

  1. "This function defined inside a class is indeed a function, and not a method; it can (or in some cases must) be looked up from the class itself rather than an instance; no instance is required to call it, as it doesn't use any instance data"

The third one extends and re-interprets the analogy from the fourth: it's no longer really about storage, but it is about "we don't have to have a specific instance in mind to use this".

  1. "This top-level function or data, although it is global within the current file, has 'internal linkage'; it shall not be visible as part of the public interface of this 'translation unit' or module"

The second one doesn't have very much connection, except that C has historically preferred to re-use an existing keyword (even in confusing ways) rather than adding new keywords that might conflict with existing code. The meaning I already discussed for the static keyword wasn't meaningful at file scope, or for functions, so they repurposed the keyword in those contexts to mean "no external linkage".

$\endgroup$
1
  • $\begingroup$ To be clear, when you say "a class is usually a singleton", you're talking about an in-memory representation of the class itself, yes? $\endgroup$ Commented May 25 at 6:33
5
$\begingroup$

Apart from the internal-linkage meaning in C, it means there is only one copy of the variable. More relevant to the English word "static", it means the variable is always allocated in the same memory location. This explains what it means for local variables and class variables.

When a class variable is always stored in the same memory location, an instance of the class isn't required in order to access it. This second, related, interpretation is also valid for class functions.

$\endgroup$
2
$\begingroup$

The thing in common is, the variable would be allocated in a place different from what someone would usually expect for the same symbolic location.

For #1, the symbol is within the function, but the variable is allocated in the global scope.

For #4, the symbol is list along with symbols in object instances, but the variable is allocated in the class (equivalent to being allocated globally in most cases). If we think arrays with a specific index type and functions with the same parameter type are alike, this could similarly extend to #3, as static functions are what static fields would be changed into if they become dynamically generated.

#2 is not like the others. If we don't care about the low-level details about linking, it is more like allocating the variable normally, but changing where the symbol would exist. Someone may also think the linking position is the real allocation, so it changes allocation. But in any case, it differentiates between symbol and allocation.

You may change them to different words if you want, especially for #2. But it may become more confusing if your language ends up having more ways to allocate differently from the symbol.

One example is, some languages have "traits" or "mixins" that could contain static variable definitions, that becomes different variables if used by multiple classes. Other languages consider them just like classes and there would be only one such variable for each definition. So, someone may come up with the idea of supporting both. You may use multiple keywords to differentiate them, but if you already used multiple keywords, and only found this use case afterwards, you might find none of your keywords are descriptive enough for either case. A better alternative could be static(class), static(mixin). (This is just an example. It could also be implemented using a CRTP templated class inheriting from a normal class, by putting two kinds of statics in different places, in languages with only one kind of static.)

My definition would also cover the possible potential cases that you could call them dynamic. The key point is the "dynamicities" are different, whether it is more static or more dynamic, or something else. This concept is referred by "static" only because it is more commonly used. So I agree it is not a good term. It could be simply called "allocated globally", if someone could make it more precise, and shorter, or simply denoted by symbol character(s), to make it practical.

$\endgroup$
2
$\begingroup$

The general meaning of the word static, as you might find in a dictionary, is "unchanging". In computing, this is generally used for items whose state doesn't change due to dynamic context.

So a static local variable in a function doesn't lose its value when the function execution ends. Contrast this with automatic variables, which may have a different value in each call.

Static member variables are not dependent on which instance of the class is being used, they're unchanged across all instances.

However, there are other uses of the keyword that don't really express this "unchanging" nature. Sometimes language designers simply reuse an keyword rather than making up a new keyword, to minimize the number of reserved words in the language. This is essentially what happened when static was coopted in C for global functions and variables that are not exported; the "unchanging" sense was not needed for them, since global state is by definition not dependent on local context, so they could arbitrarily assign this other meaning to it.

$\endgroup$
2
  • $\begingroup$ It does seem that they reuse keywords, but it'd be nice if there were more obvious logic behind the choice. $\endgroup$ Commented May 25 at 6:32
  • $\begingroup$ That would be nice, but sometimes there isn't an existing keyword that's obviously appropriate. C23 just added another new meaning for static -- it's used when specifying the size of an array parameter. $\endgroup$
    – Barmar
    Commented May 25 at 22:58
1
$\begingroup$

From a historic perspective, what they once had in common is that the underlying memory of the representing entity is a static value. It is in essence a constant location with potentially non-constant content. The word makes perfect sense from a static vs. dynamic location perspective which was correct at that time.

From today's perspective, it looks a bit obscure indeed. There are basically two reasons. The first is that adjacent concept have emerged. Linkage is a lot more complex: there is also ODR and weak and others. ASLR causes static values to be in random locations.

The second reason is philosophical abuse of the concept. What I mean by that is reusing the term for constructs that look similar from a philosophical perspective that are not from an engineering perspective. An example would be static methods in scripting languages where the method can change dynamically. This philosophic is tempting from a teaching and marketing perspective.

Tyr uses the keyword type for what is static in Java because it really means that the entity is associated with the enclosing type.

The concept of static variables should be avoided completely because it does not play along with threads.

Terminology in linkage should follow that of linkers if it is exposed to the programmer at all.

$\endgroup$
1
$\begingroup$

With regard to the usage static to describe file-scope objects, it may be worth noting that some linkers allowed symbol definitions and references to be treated interchangeably; if four source files each contained a definition for a 2-byte object "foo", the linker would reserve two bytes somewhere, and make all references point to it. On such systems, given

int x,y;
int test(void)
{
  return x+y;
}

a compiler would have no way of knowing where y would be placed relative to x or anything else. If, however, the code had been:

static int x,y;
int test(void)
{
  return x+y;
}

then a compiler could have picked some constants __X and __Y, such that any use of x could be replaced with ((int*)__STATIC_BASE)[__X], and y could be treated similarly.

$\endgroup$
2
  • $\begingroup$ Ah, so here the term "static" is meant to convey "fixed position"? $\endgroup$ Commented May 25 at 6:31
  • $\begingroup$ @KarlKnechtel: That's how I would interpret it. Some assemblers and linkers may have been able to accommodate some forms of address arithmetic on such things that would not be possible with global symbols. $\endgroup$
    – supercat
    Commented May 26 at 19:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .