Doppelte Static Variable

Gast #4958242
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?
Gast #4958247
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
}
Persönliche Seite #4958618
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.
#4958656
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.
Gast #4958668
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 */
#4958686
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
#4958691
> 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.
#4958764
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.
#4958823
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.
#4958858
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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.