static (keyword)
static (in Visual Basic Static and Shared ) is a keyword in various programming languages such as B. Java , C , C ++ , C # , Visual Basic Classic and Visual Basic .NET . The keyword is an addition to the declaration of variables and functions . It has very different meanings in different contexts, which can affect the lifetime, the linker and classes, or just trigger compile warnings. In C and C ++, it is among the keywords that have the most different meanings. In C # and VB (.Net), however, the meaning is clear. This article covers usage in the above (commonly used) languages. The keyword can also appear in other (less frequently used) programming languages and usually also has one of the meanings listed here.
use
use | Programming type | Place of use | programming language |
---|---|---|---|
Storage class (storage duration) | procedural | Method level variable | C, C ++, VB ( Static ) and VB.NET ( Static ) |
Linkage | procedural | Variable or method at module / file level | C, C ++ |
Class member without instance binding | object-oriented | Class-level variable or method | C ++, Java, VB.NET ( Shared ), C # |
Minimum size for array parameters | neutral | Array definition in the signature of a method | C99 |
static as a storage class
The storage class ( English storageClass ) static defines the "lifetime" of a variable.
The lifetime of a global variable (variables at module / file level) begins with the program start (for global variables) and ends with the end of the program: They always have the storage class "static" ( static storage duration ). On the other hand, you can use the keyword static
to influence the storage class at the method level . By default, the lifetime of variables at method level is limited to the method call, so they are removed again when the method is exited. Variables with the keyword static
, on the other hand, have the static storage class and therefore retain their values even after the method is called. The opposite of the static
keyword in this context is omitting the keyword (or using the keyword in C auto
).
In purely procedural programming languages, the keyword is often used in this context in order to achieve the lowest possible visibility of the variables. An alternative to a variable in a method with a static storage class is a variable at module / file level that is not made available by the linker (see #Linkage ). However, this can also be accessed from another method in the same module / file.
In object-oriented programming languages, well-suited alternatives are available for the lowest possible visibility . In addition, the encapsulation concepts often also require cross-method access. The biggest restriction, however, is that variables are often required in the class context, while variables of the static storage duration work across classes. Therefore, the keyword is used in this meaning there considerably less often. If you need static storage duration , you can instead use private static (see #static and Shared for class members ) class variables, which are also accessible for other methods of the class, but which fit much better into the systematics of object-oriented programming.
The meaning of static
as a storage class can be applied in C and C ++. The keyword (common notation:) was Static
also introduced in Visual Basic Classic and adopted in Visual Basic .Net for reasons of compatibility. C #, on the other hand, dispenses with static
this meaning of the keyword in favor of a clear meaning of the keyword.
Example in C and C ++
int summiere(int s)
{
static int summe = 100; // Variable wird beim ersten Durchlauf der Deklaration initialisiert.
summe += s;
return summe;
}
Example in VB.Net and VB
VB.Net:
Public Function Summiere(ByVal s As Integer) As Integer
Static summe As Integer = 100
summe += s
Return summe
End Function
VB works analogously, taking into account the missing syntax elements (e.g. the missing return), see for example for VB6.
Linkage
The linkage of a symbol indicates (such as. For example, a variable or function name) as the symbol at the left hand is dealt.
Global variables in C have external linkage by default , that is, they are visible from other translation units and exist only once in the final program. All methods access the same variable. If a symbol is defined with external linkage in several translation units (and not just declared!), There will be a linker error ( double definition error ), since it is unclear which of the two variables should be used in all other translation units.
In order to define variables and functions for each translation unit, you have to declare them with internal linkage . In C and C ++, this is done static
using the keyword when declaring a global variable or function. The variable / function is no longer made available to the linker, so that the other translation units can no longer (directly) access it ( access modifier ). At the same time, it is possible for other translation units to define variables and functions that have the same name but nothing to do with one another.
The use of the static
keyword for linkage purposes only exists in C and C ++. Java, C # and VB (.Net) do not have linkers in this form and also do not allow the definition of variables at module / file level.
In procedural programming, using the keyword for all methods that should not be accessible from the outside and for all variables is considered good style. (If necessary, the variables can be accessed via a getter and a setter as an access function .) When separating the module interface (.h file) and code (.c file), internally linked members, unlike externally linked members, are not included in the .h file, but are only located in the .c file.
Example in C or C ++
The following example shows how static
linking is used and why the keyword is necessary in this sense.
Translation unit foo.c
static int x; // internal linkage
extern int y; // nur Deklaration!
// => nicht alleine Lauffähig.
int z; // external linkage in beiden Dateien
const int c = 42; // external linkage in C, internal in C++
static int f() {return 0;} // internal linkage
int g(); // nur Deklaration!
// => nicht alleine Lauffähig.
int h() {return 2;} // external linkage in beiden Dateien
|
Translation unit bar.c
static int x; // internal linkage
int y; // external linkage, ergänzt beim Zusammenlinken
// die Deklaration in foo.c um die Definition.
int z; // external linkage in beiden Dateien => Fehler
const int c = 42; // external linkage in C, internal in C++
static int f() {return 0;} // internal linkage
int g() {return 1;} // external linkage, ergänzt beim Zusammenlinken
// die Deklaration in foo.c um die Definition.
int h() {return 2;} // external linkage in beiden Dateien => Fehler
|
The variables x
and the functions f()
are in both files static
. After compiling, they are not made available to the linker and therefore have nothing to do with each other despite their same name.
The variable y
and the function g()
are declared in the file foo.c with extern
or without a method body. The file foo.c can therefore not run on its own; instead, the linker is prompted in the compiled file to insert the missing function or variable from the bar.c file. The bar.c file, on the other hand, would also run without a link; the compiler makes the variables y
and functions of g()
the bar.c file available to the linker so that the linker can add the missing symbols in foo.c. Once both files are linked, both files use the same variable or function.
The variables z
and the functions h()
are defined in both files and are made available to the linker in both files. If you try to compile these two files and then link them together, there will be linker errors for the variable z
and the function h()
, as these were each defined twice, which would make it unclear which of the two instances should be used.
C and C ++ behave differently with the default linkage of the const
variables c
, for which no keyword was specified. While in C this still has external linkage and thus the above example would also c
give a linker error (analogous to the variables z
), in C ++ it has internal linkage and thus exist per compilation unit . So there would be no linker error with C ++.
In languages with classes, there can be class functions that have something to do with the class but do not require any data from instances of this class. There can also be classes and variables for which, for technical reasons, it does not make sense to create more than one instance. For this purpose, declarations of member variables and functions can be provided with the keyword static
. It indicates that this variable or function exists and can be used without an instance of the class. This is usually the most common use of the keyword in object-oriented languages.
In C ++, C # and Java the static
keyword is used for this purpose, but VB.Net uses the Shared
keyword (translated: shared (with other class instances) ) for this purpose in order Static
to avoid a context-dependent meaning of the keyword after this for reasons of compatibility with VB Classic it is already used in the meaning as a storage class .
Static variables and methods are called because of their purpose without a class instance, so that often no instance is available via which the method can be called. The usual syntax Variable.Methode()
or Variable->Methode()
is therefore omitted. In order to still be able to access them, the methods are called using the name of the class ( Klasse.Methode()
or Klasse::Methode()
). To prevent the programmer from misjudging the effects of his programming, in some programming languages it is forbidden to call a static class member via an instance or compile warnings are generated.
Static constructors
Variables that are not bound to a class instance cannot be initialized using normal constructors. The languages use different options for how such variables can be initialized: In C ++, the variable only represents a declaration that is to be written later (analogous to variables at module level, usually in the cpp file, so that the variable is only used once in the compiled program exists) and can be given a default value . In Java, C # and VB.Net, however, the static members are initialized directly or using methods similar to constructors ( static initializers , static constructors ). These constructors have no parameters and are implicitly called once before a class member is called for the first time or a class instance is created. These static initializers are also identified with the keyword static
or Shared
as such, but the details of the syntax differ between Java and C # or VB.Net.
Example in C ++
//Header:
class C
{
public:
int i;
static int s; // nur Deklaration!
};
//Source:
int C::s = 42; // Definition & Initialisierung der statischen Membervariablen
int usage()
{
C::s = 1; // Benutzung ohne ein Objekt vom Typ C
C c;
c.i = 17;
c.s = 0; // möglich, aber Gefahr dass der Programmierer die Auswirkungen falsch einschätzt. Compiler kann hier warnen.
}
Example in Java
A separation between declaration and definition is not necessary in Java, C # and VB.Net, the compiler and the runtime environment independently ensure that the variable occurs only once in the executing program.
class Beispiel {
public static int s; // statische Variable, Initialisierung im statischen Initializer.
public static int t = 5; // statische Variable mit Standardwert
public int i; // Klassenvariable, Initialisierung im Konstruktor
public Beispiel() { // Konstruktor, Initialisierung von i im Konstruktor.
i = 0;
}
static { //Statischer Initializer: Syntax in Java: nur ein static-Schlüsselwort
s = 42; //Statischer Initializer, Initialisierung von s im statischen Initializer
}
public static void usage() {
Beispiel.s += 1; //Aufruf über den Klassennamen
Beispiel b = new Beispiel();
b.i += 1; //Aufruf der Klassenvariable über eine Instanz.
b.s += 1; // Keine Kompilierwarnung in Java.
}
}
Example in C #
class Beispiel
{
public static int s; // statische Variable, Initialisierung im statischen Konstruktor.
public static int t = 5; // statische Variable mit Standardwert
public int i; // Klassenvariable, Initialisierung im Konstruktor
public Beispiel() // Konstruktor, Initialisierung von i im Konstruktor.
{
i = 0;
}
static Beispiel() // statischer Konstruktor: Syntax in C#: Konstruktor mit static-Schlüsselwort und ohne Parameter und Zugriffsmodifikator
{
s = 42; // Initialisierung von s im statischen Konstruktor
}
public static void Usage()
{
Beispiel.s += 1; // Aufruf über den Klassennamen
Beispiel b = new Beispiel();
b.i += 1; // Aufruf der Klassenvariable über eine Instanz.
b.s += 1; // Erzeugt einen Kompilierfehler (CS0176), um Fehleinschätzungen zu vermeiden.
}
}
Example in VB.NET
Public Class Beispiel
Public Shared s As Integer 'Statische Variable, Initialisierung im statischen Konstruktor.
Public Shared t As Integer = 5 'Statische Variable mit Standardwert
Public i As Integer 'Klassenvariable, Initialisierung im Konstruktor
Public Sub New() 'Konstruktor, Initialisierung von i im Konstruktor.
i = 0
End Sub
Shared Sub New() 'Statischer Konstruktor: Syntax in VB.Net: Konstruktor mit Shared-Schlüsselwort und ohne Parameter und Zugriffsmodifikator
s = 42 'Statischer Konstruktor, Initialisierung von s im statischen Konstruktor
End Sub
Public Shared Sub Usage()
Beispiel.s += 1 'Aufruf über den Klassennamen
Dim b As New Beispiel()
b.i += 1 'Aufruf der Klassenvariable über eine Instanz.
b.s += 1 'Erzeugt eine Kompilierwarnung (BC42025), um Fehleinschätzungen zu vermeiden.
End Sub
End Class
static for array parameters
Since arrays in C are passed to functions as a "pointer to the first element", the function does not know the size of the array. In C99 , the option was created to include a minimum size when declaring the function . On the one hand, this allows a better type check at compile time and - especially in connection with the restrict
keyword - the generation of high-performance codes.
Similar tests can be carried out in VB.Net and in C # as of .Net 4.0 within the framework of the far more powerful code contracts . The static
syntax in the signature of the method, as in C, is not supported. This meaning was not adopted in C ++ either.
- example
void hash(unsigned char digest[static 64], const char* data, size_t size);
int main()
{
unsigned char buffer[32];
hash(buffer, data, length); // Compilerwarnung: hash erwartet mind. 64 Bytes, buffer ist aber kleiner!
}
Web links
- static in C ++, MSDN (English)
- static in C #, MSDN (German)
- Shared in VB.Net, MSDN (German)
- Static in VB.Net, MSDN (German)
- Java language specification for static fields , methods and static initializers (English)
Individual evidence
- ^ Peter Aitken: Preserve procedure variables with Static in VB6 . techrepublic.com. September 8, 2005. Retrieved November 8, 2019.