static, extern
-
hey leute,
ich hab mal eine kurze frage zu den schlüsselworten "static" und "extern". ich leite sie am besten mal direkt mit einem codebeispiel ein:
// DATEI 1 #include <stdio.h> static int tmp=1; extern int tmp; int main(void) { printf("tmp: %i\n",tmp); return 0; } //DATEI 2 int tmp=2; //Ausgabe: tmp: 1
mich wundert das ganze etwas. zunächst hatte ich eigentlich einen kompilerfehler erwartet(doppeldeklaration der variablen "tmp"). als dies jedoch nicht der fall war hätte ich zumindest erwartet, dass die 2 deklaration gültig ist und die ausgabe somit "tmp: 2" wäre.
Kann mir vllt einer von euch sagen, wie das in C gehandhabt wird?
komischerweise ergeben auch sachen wie:
static int a=5; static int a; //oder static int a; static int a=5;
keine fehler, jedoch wohl
static int a=6; static int a=5;
wie gesagt, wäre super wenn mir da einer etwas weiterhelfen könnte
schönen sonntag wünsche ich allen
-
MatheStein schrieb:
komischerweise ergeben auch sachen wie:
static int a=5; static int a; //oder static int a; static int a=5;
keine fehler, jedoch wohl
static int a=6; static int a=5;
Das liegt daran, daß du globale Variablen nicht nur definieren, sondern auch nur deklarieren kannst (wenn sie schon definiert wurden); was für lokale Variablen keinen Sinn ergeben würde.
-
^^naja, extern-deklarationen werden von 'echten' variablen überdeckt. der grund dafür, das es kein warning gibt, ist wohl, damit das 'extern' auch in einem header-file stehen kann, das auch von dem c-file includiert werden kann, in dem die variable tatsächlich angelegt wird.
-
oh gott ich verstehe nichts
wenn ich eine variable definiere durch beispielsweise "static int a=5" dann ist doch deklaration implizit gegeben oder nicht?
was genau ist jetzt mit "deklaration, wenn die variable schon definiert wurde", gemeint? sie ist ja demach schon deklariert worden, wenn sie definiert ist.@;fricky:
wenn ich das ganze richtig verstanden habe, müsste aber in der c-file trotzdem noch drauf geachtet werden, alle globalen variablen vor den "include"s zu definieren oder?so wie ich das verstanden habe, packen wir eine "extern"-variable in einen header und der header nimmt sich dann die variable aus dem c-file der sie includiert oder einer der mit kompilierten dateien. könnte man die deklaration per "extern" in dem header nicht auch ganz weglassen?
kann auch gut sein, dass ich dich jetzt ganz falsch verstanden habe
hast du vllt ein kleines code-beispiel an dem man sich orientieren könnte?
gruß
-
MatheStein schrieb:
so wie ich das verstanden habe, packen wir eine "extern"-variable in einen header und der header nimmt sich dann die variable aus dem c-file der sie includiert oder einer der mit kompilierten dateien. könnte man die deklaration per "extern" in dem header nicht auch ganz weglassen?
nee, ich meine ungefähr sowas:
erstmal eine .h datei, die 'nen neuen typ einführt und ein objekt davon als extern deklariert. das objekt selbst ist in einer anderen datei.// header.h ... typedef struct mystruct { int member1; .... } mystruct_t; ... extern mystruct_t GlobalMyStruct;
dann ein c-file, in dem das objekt angelegt wird...
// wichtiger_code.c ... #include "header.h" ... mystruct_t GlobalStruct = ...; ...
^^ dieses C-file braucht das #include wegen des typedefs
andere datei:// viel_wichtigerer_code.c ... #include "header.h" ... void f() { int x = GlobalMyStruct.member1; ... }
^^dieses c-file braucht auch das include wegen des typedefs aber muss zusätzlich noch auf das globale objekt zugreifen.
-
ok verstanden habe ich es jetzt auf jeden fall
danke!
was ist denn der vorteil einer solche vorgehensweise?
anstatt "extern bla bla bla" in der c.datei stehe zu haben, steht sie jetzt im header. Einfach nur die säuberliche trennung von deklaration und definition wie bei funktionen und "normalen" globalen variablen auch oder gibts da noch tieferliegende anwendungen für?gruß
-
wenn ich eine variable definiere durch beispielsweise "static int a=5" dann ist doch deklaration implizit gegeben oder nicht?
Ja. Aber die Variable ist eben nur in dieser Übersetzungseinheit sichtbar.
was genau ist jetzt mit "deklaration, wenn die variable schon definiert wurde", gemeint? sie ist ja demach schon deklariert worden, wenn sie definiert ist.
Ja. Aber eine externe Variable musst du als extern deklarieren, wegen den unterschiedlichen Übersetzungseinheiten. Wo anders ist sie natürlich schon definiert und damit auch deklariert worden.
-
was ist denn der vorteil einer solche vorgehensweise?
Was die Namenskonflikte angeht, die du am Anfang erwähnt hast: ich weiß auch nicht so recht, was das zu bedeuten hat. Vielleicht kommt fricky noch drauf, der denkt konkreter darüber nach als ich.
Edit: Grammatik
-
ach so war das gemeint, hab das jetzt auch verstanden
dir auch vielen dank
gibt es eigentlich gelegenheit für die es sich lohnt eine lokale variable (innerhalb einer funktion, anweisungsblock etc) als "static" zu deklarieren? so gesehen sind doch alle lokalen variablen implizit schon "static" oder?
-
gibt es eigentlich gelegenheit für die es sich lohnt eine lokale variable (innerhalb einer funktion, anweisungsblock etc) als "static" zu deklarieren? so gesehen sind doch alle lokalen variablen implizit schon "static" oder?
Bei lokalen Variablen läuft ein
static
auf etwas anderes hinaus: nämlich darauf, dass die Variable den Wert behält, auch nachdem die Funktion verlassen wurde.
-
ach stimmt, das hatte ich jetzt total verpennt
vielen dank euch allen!!
-
mngbd schrieb:
Was die Namenskonflikte angeht, die du am Anfang erwähnt hast: ich weiß auch nicht so recht, was das zu bedeuten hat. Vielleicht kommt fricky noch drauf, der denkt konkreter darüber nach als ich.
naja, würde es einen namenskonflikt geben (ein warning, error oder so), dann dürfte die datei, die das objekt anlegt, den header nicht #includen (weil der compiler dann die variables selbst, wie auch die extern-deklaration sehen würde). ich bin mir nicht sicher, ob das der grund ist, warum TYP x; sowie extern TYP x; gleichzeitig möglich sind. aber es könnte einer sein.