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
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?
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
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".
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.
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?
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
Ja, da hab ich wohl irgendwas durcheinander geworfen. Irren ist menschlich, Danke für die Aufklärung.
Hab's jetzt mit der Dekleration mit "extern" im Headerfiler und dem Anlegen in einem C-File gelöst .... Danke. Gruß Eric
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
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.
Huch schrieb: > "extern static"? Wasn das? Das nimmt jemand, der bei einer Funktion const void als Rückgabetyp schreibt.
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.
Ah, jetzt wird ein Schuh draus, also ich kann dann mit static quasi das extern verhindern. Danke!
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).
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
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.
> 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.
Man kann die static Variablen bei der Definition auch initialisieren. Was sinnvollerweise auch nur einmal erfolgt.
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.
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
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?
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.
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?
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.
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
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.