Forum: Compiler & IDEs Verständnisfrage static


von Eric (Gast)


Lesenswert?

Hallo!

Ich habe eine kurze allgemeine Verständisfrage zu einer 
static-Variablen.
Wenn ich eine Variable als static in einem Headerfile anlege und dieses 
Headerfile in mehreren c-Filed inkludieren, von denen aus ich auf diese 
Variable zugreife, verwenden dann alle c-Files die gleiche Variable, 
oder jeder seine eigene?

Gruß
Eric

von Huch (Gast)


Lesenswert?

Das ist dann in jedem Objekt(-file) eine eigene Variable. Das ist ja 
gerade und genau der Sind und Zweck von "static". ;-) Was sagt Dein 
C-Buch dazu?

Warum willst Du überhaupt eine static-Variable in einem Header-File 
definieren und dieses Header File in verschiedenen C-Files per include 
einbinden?

von us73 (Gast)


Lesenswert?

Well, so einfach gehts nicht. Da meckert der Linker, weil er in mehreren 
Objects globale Variablen mit gleichem Namen findet.

Das Ding muss einmal existieren (static) und von den anderen nur noch 
referenziert werden (extern static).
extern besagt hier, dass Du dafür Sorge trägst, dass beim Zusammenlinken 
realer Speicheplatz für die Variable z.V. gestellt wird. Und das hast Du 
ja durch die Deklaration als "static" in genau einem anderen File getan.

Hoffentlich verständlich genug erklärt....

Uwe

von Huch (Gast)


Lesenswert?

"extern static"? Wasn das?

von wassollichhiereingeben? (Gast)


Lesenswert?

us73 schrieb:
> Well, so einfach gehts nicht. Da meckert der Linker, weil er in mehreren
> Objects globale Variablen mit gleichem Namen findet.
Vorsicht: Der Linker vom GCC fasst die Variablen stillschweigend zu 
einer einzigen zusammen, such mal nach "-fno-common".

von Thomas (Gast)


Lesenswert?

Eric schrieb:
> Wenn ich eine Variable als static in einem Headerfile anlege und dieses
> Headerfile in mehreren c-Filed inkludieren, von denen aus ich auf diese
> Variable zugreife, verwenden dann alle c-Files die gleiche Variable,
> oder jeder seine eigene?

Deklariere die Variable im Headerfile als extern und in einem der 
c-Files ohne extern und du erreichst, dass die Variable nur einmal 
angelegt wird und aus allen c-Files, die das Headerfile inkludieren, auf 
sie zugegriffen werden kann.

von wassollichhiereingeben? (Gast)


Lesenswert?

wassollichhiereingeben? schrieb:
> us73 schrieb:
>> Well, so einfach gehts nicht. Da meckert der Linker, weil er in mehreren
>> Objects globale Variablen mit gleichem Namen findet.
> Vorsicht: Der Linker vom GCC fasst die Variablen stillschweigend zu
> einer einzigen zusammen, such mal nach "-fno-common".

Ich machs wie Intel:
Errata - Das scheint nicht zu stimmen. Ich kann problemlos 2 static 
Variablen mit gleichem Namen in 2 verschiedenen C-Dateien eines selben 
Projektes anlegen, die Verhalten sich ganz normal wie zwei unabhängige 
Variablen. Der Linker sagt nix, mit oder ohne -fno-common. Was hab ich 
nicht verstanden?

von Oliver (Gast)


Lesenswert?

wassollichhiereingeben? schrieb:
> Was hab ich
> nicht verstanden?

Nix. Genau das soll doch auch passieren.

Jede Variable, die als static deklariert ist, gilt nur in ihrer 
Compilationseinheit. Und dabei ist es egal, ob das static in einer 
headerdatei steht, oder nicht. Wird die headerdatei in mehreren 
undabhängingen C-Dateien includert, werden eben mehrere unabhängige 
Variablen angelegt. Eine Fehlermeldung darf es dabei gar nicht geben, 
denn das ist ja genau der Sinn von static.

Die Option -fno-common wirkt auf globale Variablen (ohne static). Gibt 
es davon mehrere geliche Namens, fasst gcc die ohne -fno-common 
stillschweigend in einem Speicherplatz zusammen.

Oliver

von wassollichhiereingeben? (Gast)


Lesenswert?

Ja, da hab ich wohl irgendwas durcheinander geworfen. Irren ist 
menschlich, Danke für die Aufklärung.

von us73 (Gast)


Lesenswert?

Huch schrieb:
> "extern static"? Wasn das?

Arg, "extern".

Uwe

von Eric (Gast)


Lesenswert?

Hab's jetzt mit der Dekleration mit "extern" im Headerfiler und dem 
Anlegen in einem C-File gelöst ....

Danke.

Gruß
Eric

von Ulrich (Gast)


Lesenswert?

static <-> extern
Wenn ich eine Variable in mehreren c-files nutzen will, muss ich sie ja 
im header extern machen und in einem c file (am sinnvollsten in dem zum 
header gehörenden) deklarieren.
Aber irgendwie verstehe ich nicht, wieso ich dann eine Variable die 
nicht extern ist, mit static versehen kann/muss. Ohne das extern, ist 
sie doch woanders auch nicht nutzbar, also im prinzip doch schon static.
kopfkratz

von Stefan E. (sternst)


Lesenswert?

Ulrich schrieb:
> Ohne das extern, ist sie doch woanders auch nicht nutzbar,

Doch ist sie. Wenn in einer C-Datei "int test;" steht, dann kann auch in 
jeder anderen C-Datei über "extern int test;" auf diese Variable 
zugegriffen werden. Wenn du aber "static int test;" schreibst, dann geht 
das nicht. Dann kommst du in anderen C-Dateien nicht über "extern" an 
diese Variable ran.

von Klaus W. (mfgkw)


Lesenswert?

Huch schrieb:
> "extern static"? Wasn das?

Das nimmt jemand, der bei einer Funktion const void als Rückgabetyp 
schreibt.

von Andreas B. (andreas_b77)


Lesenswert?

Ulrich schrieb:
> Ohne das extern, ist
> sie doch woanders auch nicht nutzbar, also im prinzip doch schon static.

"extern" heißt, die Variable nicht zu erzeugen sondern von woanders zu 
referenzieren. "static" (bei globalen Variablen) heißt, die Variable 
nicht zu exportieren, d.h. gar nicht erst als Symbol für den Linker 
sichtbar zu machen.

Ohne weder "extern" noch "static" wird eine globale Variable erzeugt und 
in die Symboltabelle der Objektdatei eingetragen, so dass sie von 
anderen Objektdateien (per "extern") eingebunden werden kann.

von Ulrich (Gast)


Lesenswert?

Ah, jetzt wird ein Schuh draus, also ich kann dann mit static quasi das 
extern verhindern. Danke!

von DJ T. (Gast)


Lesenswert?

Ein Anwendungszweck von "static" ist es, modul-lokale Variablen gezielt 
zu "verstecken", d.h. zu verhindern, daß andere Module darauf zugreifen 
können.
Im Grunde kann/soll man alle Variablen, die nur innerhalb eines Moduls 
benutzt werden, als "static" anlegen.

Bitte nicht verwechseln:
Innerhalb einer Funktion hat "static" ein ganz andere Bedeutung. Dort 
bedeutet "static", dass die Variable auch nach Verlassen der Funktion 
noch existiert und ihren Wert beibehält (während lokale Variablen 
verloren gehen).

von Simon B. (nomis)


Lesenswert?

Sebastian F. schrieb:
> Innerhalb einer Funktion hat "static" ein ganz andere Bedeutung.

Nur so als Nitpick: "ganz anders" ist die Bedeutung eigentlich nicht.

Es sind genauso Variablen mit eingeschränkten Sichtbarkeitsbereich, die 
genauso während des ganzen Programmablaufs gültig sind (und genauso mit 
einem Startwert initialisiert werden können).

Wobei eine spannende Frage ist, wann static-Variablen in einer Funktion 
angelegt werden: Bei Programmstart? Oder erst beim ersten Aufruf der 
betreffenden Funktion?

Viele Grüße,
        Simon

von Peter II (Gast)


Lesenswert?

Simon Budig schrieb:
> Wobei eine spannende Frage ist, wann static-Variablen in einer Funktion
> angelegt werden: Bei Programmstart? Oder erst beim ersten Aufruf der
> betreffenden Funktion?

Kann doch nur beim Programmstart sein. Woher soll er denn später wissen 
ob die funktion schon mal aufgerufen wurden ist.

von Klaus W. (mfgkw)


Lesenswert?

> Nur so als Nitpick: "ganz anders" ist die Bedeutung eigentlich nicht.


naja....

bei lokalen Variablen hat man die eingeschränkte Sichtbarkeit ja ohnehin 
schon durch die lokale Deklaration.
Durch das static verschiebt sich ihre Anlage aber vom Stack in den 
statischen Datenbereich.
-> Position ändert sich, Sichtbarkeit bleibt

Globale Variablen dagegen sind sowieso statisch, durch das static 
schränkt sich die Sichtbarkeit ein.
-> Position bleibt, Sichtbarkeit ändert sich

Für globale Variablen halte ich "static" für einen der mißlungensten 
Punkte in C.
Ich kann mir das nur erklären, daß man irgendwann dafür noch ein 
Schlüsselwort brauchte, und static bis dahin nur für lokale Variablen 
vorgesehen war, also bei globalen einfach unbenutzt war. Insofern muß 
man noch zufrieden sein, daß die Wahl nicht auf register fiel.

von DirkB (Gast)


Lesenswert?

Man kann die static Variablen bei der Definition auch initialisieren.
Was sinnvollerweise auch nur einmal erfolgt.

von Klaus W. (mfgkw)


Lesenswert?

Peter II schrieb:
> Simon Budig schrieb:
>> Wobei eine spannende Frage ist, wann static-Variablen in einer Funktion
>> angelegt werden: Bei Programmstart? Oder erst beim ersten Aufruf der
>> betreffenden Funktion?
>
> Kann doch nur beim Programmstart sein. Woher soll er denn später wissen
> ob die funktion schon mal aufgerufen wurden ist.

Speichermäßig angelegt wird sie bei Programmstart.

Die Initialisierung mit dem Startwert dagegen ist nur bei C bei 
Programmstart, bei C++ dagegen beim ersten Durchlaufen der Funktion.

von Simon B. (nomis)


Lesenswert?

Klaus Wachtler schrieb:
>> Nur so als Nitpick: "ganz anders" ist die Bedeutung eigentlich nicht.
> naja....

OK, auf die Bedeutung des Worts "static" habe ich zugegebenermaßen gar 
nicht geachtet, da hast Du natürlich völlig recht. Vom Endergebnis her 
betrachtet landet man in beiden Fällen aber bei einer von der 
Sichtbarkeit her eingeschränkten, statischen Variable. Ob das nun die 
cleverste Wahl für das Schlüsselwort war sei mal dahingestellt...  :-)

Viele Grüße,
        Simon

von Peter II (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> Die Initialisierung mit dem Startwert dagegen ist nur bei C bei
> Programmstart, bei C++ dagegen beim ersten Durchlaufen der Funktion.

wie ist das überhaupt bei C++ definiert? ist die static Variable Objekt 
übergreifen in den Methoden gleich oder hat jeden Objekt seine eigene 
static variable?

von Klaus W. (mfgkw)


Lesenswert?

Peter II schrieb:
> wie ist das überhaupt bei C++ definiert? ist die static Variable Objekt
> übergreifen in den Methoden gleich oder hat jeden Objekt seine eigene
> static variable?

static ist static, also nur einmal je Programm.

Wenn du also in einer Methode ein static int i definierst, dann ist das 
eine Variable für alle Instanzen der Klasse. Genau genommen natürlich 
gar nicht für die Instanzen, sondern eben für die Klasse.

Allerdings natürlich ebenso wie in normalen Funktionen: mehrfache static 
int i (in verschiedenen Blöcken einer Funktion oder über mehrere 
Funktionen verteilt) werden zu entsprechend vielen Variablen.

Ebenso beim Ableiten: wenn man ein static-Element hat, und definiert in 
einer Ableitung nochmal eines mit demselben Namen, dann gibt es zwei 
Variablen pro Programm, egal wieviele Objekte man davon bildet.

PS: das gilt natürlich nur für je ein laufendes Programm.
Wenn ein Programm mehrfach gestartet wird und diese parallel laufen, 
mutliplizieren sich die Variablen entsprechend.

von Peter II (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> Peter II schrieb:
>> wie ist das überhaupt bei C++ definiert? ist die static Variable Objekt
>> übergreifen in den Methoden gleich oder hat jeden Objekt seine eigene
>> static variable?
>
> static ist static, also nur einmal je Programm.

gut so hätte ich das auch erwartet.

aber das hatte mich ein wenig verunsichert:

Klaus Wachtler schrieb:
> Die Initialisierung mit dem Startwert dagegen ist nur bei C bei
> Programmstart, bei C++ dagegen beim ersten Durchlaufen der Funktion.

dann müsste ja das system sich auch noch merken welche Variable es schon 
Initialisierung hat. Was ist bei 2 Threads die gleichzeitig eine Objet 
der gleich Klasse anlegen?
Das ganze ist doch wesentlich komplexer als der C ansatz - bist du 
sicher das das bei c++ so gemacht wird?

von Klaus W. (mfgkw)


Lesenswert?

Peter II schrieb:
> dann müsste ja das system sich auch noch merken welche Variable es schon
> Initialisierung hat.

Das ist Problem des Compilers, nicht meines.

> Was ist bei 2 Threads die gleichzeitig eine Objet
> der gleich Klasse anlegen?

Threads gibt es bislang im C++-Standard nicht :-)

Man muß also selbst für Synchronisierung sorgen, oder thread local 
storage oder sowas machen. Ansonsten teilen sich die Threads die 
static-Variable.

> Das ganze ist doch wesentlich komplexer als der C ansatz - bist du
> sicher das das bei c++ so gemacht wird?

Nein, nur so sicher wie Bjarne Stroustrup. Der erzählt das so :-)


Nochmal zur Konkretisierung:
Eine static-Variable wird in C++ nicht zwangsläufig beim Aufruf der 
Funktion intialisiert, sondern wenn der Programmfluß bei ihr 
vorbeikommt.
Also z.B. in einem if-Block (um das Wort if-Schleife zu vermeiden) nur, 
wenn die Bedingung erfüllt ist.

von Simon B. (nomis)


Lesenswert?

Peter II schrieb:
> Das ganze ist doch wesentlich komplexer als der C ansatz - bist du
> sicher das das bei c++ so gemacht wird?

Naja, C++ ist sowieso in der Hinsicht wesentlich komplexer/kaputter als 
C.

C erlaubt nur konstante Ausdrücke um statische Variablen zu 
initialisieren, C++ führt da dann plötzlich Code aus (z.B. 
Konstruktoren).

Was insbesonders bei globalen Variablen (evtl. auch in mehreren Dateien) 
spannend ist, weil die Initialisierungsreihenfolge nicht definiert ist. 
D.h. Konstruktoren die z.B. die Existenz eines anderen statischen 
Objekts voraussetzen fallen ggf. auf die Schnauze.

  http://yosefk.com/c++fqa/ctors.html#fqa-10.12

Viele Grüße,
        Simon

von Klaus W. (mfgkw)


Lesenswert?

Was wäre das Leben ohne Abenteuer...

von Peter II (Gast)


Lesenswert?

Klaus Wachtler schrieb:

> Man muß also selbst für Synchronisierung sorgen, oder thread local
> storage oder sowas machen. Ansonsten teilen sich die Threads die
> static-Variable.
das ist ja der sinn der static ich will ja nur eine haben, also auch 
alle Threads. Ich hätte bei diesem Ansatz nur angst das die Variabel in 
beiden Threads intialisiert wird.

von Klaus W. (mfgkw)


Lesenswert?

ebend

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.