Forum: Mikrocontroller und Digitale Elektronik Doppelte Static Variable


von statichochzwei (Gast)


Lesenswert?

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?

von STK500-Besitzer (Gast)


Lesenswert?

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.

von Peter II (Gast)


Lesenswert?

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.
1
int main()
2
{
3
        static char test1 = 1;
4
        {
5
           static char test1 = 1;
6
        }
7
}

geht ohne Warnung, aber so gibt es einen fehler
1
int main()
2
{
3
        static char test1 = 1;
4
        static char test1 = 1;
5
}

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Peter II schrieb:
> es gab 2 stück, sie hatten vermutlich andere Gültigkeitsbereiche.

Das ist nicht nur vermutlich, sondern tatsächlich so.
1
static char test1 = 1;
2
3
int main()
4
{
5
  static char test1 = 1;
6
  {
7
    static char test1 = 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.

von Base64 U. (6964fcd710b8d77)


Lesenswert?

Rufus Τ. F. schrieb:
> ...unterschiedliche Gültigkeitsbereiche...

Findet man unter dem Begriff "scope/scoping" auch soweit mir bekannt 
ist.

von (prx) A. K. (prx)


Lesenswert?

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.

von A. S. (Gast)


Lesenswert?

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 */

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Da bin ich letzthin erst ueber "was nettes" (unter Linux) gestolpert:
global.c:
1
#include <stdio.h>
2
#include <unistd.h>
3
4
static int bla=12345;
5
6
int main() {
7
    printf("bla@%p\n",&bla);
8
    sleep(20);
9
    return 0;
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

von Bernd K. (prof7bit)


Lesenswert?

> 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.

von Rolf M. (rmagnus)


Lesenswert?

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.

von Bernd K. (prof7bit)


Lesenswert?

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.

von Rolf M. (rmagnus)


Lesenswert?

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.

von Blechbieger (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> static char test1 =  1;
>
> int main()
> {
>   static char test1 = 1;
>   {
>     static char test1 = 1;
>   }
> }

Mit -Wshadow warnt GCC vor solchen Konstrukten.

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.