Hallo,
habe gerade mehr oder minder durch Zufall bemerkt, dass eine meiner
Variablen static doppelt vorhanden war, also
static char abc[100];
...
...paar Zeilen dazwischen
...
static char abc[100];
Der Compiler hat es nicht angemerkt.
Gab es nun mehr als eine Variable und es ist nur eine Zeitlang
gutgegangen?
statichochzwei schrieb:> Gab es nun mehr als eine Variable und es ist nur eine Zeitlang> gutgegangen?
Wenn die zweite in einer Schleife oder einem anderen eigenen Abschnitt
deklariert wurde, dann gilt diese nur dort.
statichochzwei schrieb:> Gab es nun mehr als eine Variable und es ist nur eine Zeitlang> gutgegangen?
es gab 2 stück, sie hatten vermutlich andere Gültigkeitsbereiche.
Peter II schrieb:> es gab 2 stück, sie hatten vermutlich andere Gültigkeitsbereiche.
Das ist nicht nur vermutlich, sondern tatsächlich so.
1
staticchartest1=1;
2
3
intmain()
4
{
5
staticchartest1=1;
6
{
7
staticchartest1=1;
8
}
9
}
Hier haben alle drei Variablen unterschiedliche Gültigkeitsbereiche, und
das haben sie übrigens auch dann, wenn sie nicht als static deklariert
werden.
statichochzwei schrieb:> Gab es nun mehr als eine Variable und es ist nur eine Zeitlang> gutgegangen?
Bei verschiedenen Scopes (siehe oben) sind es verschiedene Variablen.
Innerhalb des gleichen Scopes sind in C, nicht aber in C++,
Mehrfachdeklarationen unter bestimmten Bedingungen zulässig (tentative
definition). Es handelt sich dann um die gleiche Variable.
A. K. schrieb:> Innerhalb des gleichen Scopes sind in C, nicht aber in C++,> Mehrfachdeklarationen unter bestimmten Bedingungen zulässig (tentative> definition). Es handelt sich dann um die gleiche Variable.
sie dürfen vor allem nicht unterschiedlich sein (mal 100 Elemente, mal
10) und nicht an 2 Stellen Initialisiert werden.
static char abc[100];
static char abc[10]; /* geht nicht */
static char c = 'a';
static char c = 'a'; /* geht auch nicht */
static char OK;
static char OK;
static char OK;
static char OK;
static char OK;
static char OK;
static char OK;
static char OK;
static char OK = 1; /* OK */
Moin,
Da bin ich letzthin erst ueber "was nettes" (unter Linux) gestolpert:
global.c:
1
#include<stdio.h>
2
#include<unistd.h>
3
4
staticintbla=12345;
5
6
intmain(){
7
printf("bla@%p\n",&bla);
8
sleep(20);
9
return0;
10
}
Dann in einer shell:
1
wk:~$ gcc -Wall global.c
2
wk:~$ ./a.out &
3
[1] 24124
4
wk:~$ bla@0x8049650
5
./a.out &
6
[2] 24125
7
wk:~$ bla@0x8049650
8
./a.out &
9
[3] 24126
10
wk:~$ bla@0x8049650
Da gibts jetzt also 3 Prozesse und in jedem Prozess gibts die Variable
bla, und die sitzt bei allen 3 Prozessen an genau der gleichen Adresse
im Speicher. Kann aber trotzdem unterschiedliche Werte haben...
...Wunderwelt der MMU ;-)
Gruss
WK
> static char OK;> static char OK;> static char OK;> static char OK;> static char OK;> static char OK;> static char OK;> static char OK;> static char OK = 1; /* OK */
Speicher wird erst zugewiesen wenn sie irgendwo verwendet oder
initialisiert werden. Ohne Initializer wirkt die Deklaration für den
Compiler erstmal so ähnlich (aber nicht ganz so!) wie ein extern. Der
Linker weist aber dann konkreten Speicher zu wenn sie irgendwo
referenziert wird, das funktioniert auch wenn sie in verschiedenen
Übersetzungseinheiten stehen, nur eine Instanz davon wird letzten Endes
im Speicher angelegt.
Wenn es in verschiedenen C-Dateien passiert kann man es mit -fno-common
zum Fehler kommen lassen, in der selben C-Datei leider anscheinend
nicht.
Bernd K. schrieb:>> static char OK;>> static char OK;>> static char OK;>> static char OK;>> static char OK;>> static char OK;>> static char OK;>> static char OK;>> static char OK = 1; /* OK */>> Speicher wird erst zugewiesen wenn sie irgendwo verwendet oder> initialisiert werden. Ohne Initializer wirkt die Deklaration für den> Compiler erstmal so ähnlich (aber nicht ganz so!) wie ein extern.
Nein, ob initialisiert oder nicht ist egal. Es ist eine Definition, und
damit existiert die Variable dann. Natürlich darf sich der Compiler
erlauben, sie wegzuoptimieren, wenn sie nicht benutzt wird, aber das
ändert an der syntaktischen Korrektheit des Quellcode nichts.
> Der Linker weist aber dann konkreten Speicher zu wenn sie irgendwo> referenziert wird, das funktioniert auch wenn sie in verschiedenen> Übersetzungseinheiten stehen, nur eine Instanz davon wird letzten Endes> im Speicher angelegt.
Nein. Wenn sie in mehreren Übersetzungseinheiten definiert wird,
existiert sie auch mehrmals.
Rolf M. schrieb:> Bernd K. schrieb:>>> static char OK;>>> static char OK;>>> static char OK;>>> static char OK;>>> static char OK;>>> static char OK;>>> static char OK;>>> static char OK;>>> static char OK = 1; /* OK */>>>> Speicher wird erst zugewiesen wenn sie irgendwo verwendet oder>> initialisiert werden. Ohne Initializer wirkt die Deklaration für den>> Compiler erstmal so ähnlich (aber nicht ganz so!) wie ein extern.>> Nein, ob initialisiert oder nicht ist egal. Es ist eine Definition, und> damit existiert die Variable dann.
Es ist erstmal eine "tentative definition" (wirkt wie extern, kann man
mehrmals wiederholen), aber Du hast insofern recht daß sie spätestens am
Ende der Übersetzungseinheit in eine definition unmgewandelt wird.
Aber wenn sie nicht static sind dann wird der Linker nur einmal
Speicherplatz dafür anlegen, auch wenn sie in mehreren C Dateien
auftaucht. Und das ist es was man mit -fno-common verhindern kann, dann
würde er stattdessen einen Fehler schmeißen.
>> Der Linker weist aber dann konkreten Speicher zu wenn sie irgendwo>> referenziert wird, das funktioniert auch wenn sie in verschiedenen>> Übersetzungseinheiten stehen, nur eine Instanz davon wird letzten Endes>> im Speicher angelegt.>> Nein. Wenn sie in mehreren Übersetzungseinheiten definiert wird,> existiert sie auch mehrmals.
Wenn man das static weglässt existiert sie nur einmal.
Bernd K. schrieb:>> Nein. Wenn sie in mehreren Übersetzungseinheiten definiert wird,>> existiert sie auch mehrmals.>> Wenn man das static weglässt existiert sie nur einmal.
Sofern wir von einer Variable, die außerhalb einer Funktion definiert
ist, sprechen, ja. Es ging hier aber ausdrücklich um eine
static-Variable.