Forum: Compiler & IDEs globale Variable von anderem File lokal extern deklarieren möglich?


von Martin (Gast)


Lesenswert?

Hallo zusammen,

ich bin gerade am Debuggen und frage mich ob mein Konstrukt so überhaupt 
erlaubt ist. Folgender Aufbau:

afile.c:
1
uint8_t var = 0;
2
3
void foo( void )
4
{
5
    // work with var
6
    var++;
7
}

bfile.c:
1
void resetVar( void )
2
{
3
    extern uint8_t var;
4
    var = 0;
5
}

ist das so mit dem AVR-GCC erlaubt? also eine Variable die in der einen 
Datei global ist, in der anderen Datei nur lokal und trotzdem extern zu 
deklarieren?

Klar in dem Minimalbeispiel hier kann resetVar auch in afile.c 
geschieben werden und man kann sich das extern sparen, in meiner 
Anwendung geht das aber nicht so einfach und ich glaube fast, dass daran 
mein Programm scheitert.

Vielen Dank
Gruß Martin

von Oliver (Gast)


Lesenswert?

Das ist eine der Fragen, die sich mit etwas Abstand ganz plötzlich wie 
von selbst beantworten.

Was geht, ist eine lokale Variable mit gleichem Namen, wie eine globale 
(ob extern oder nicht, ist dabei egal). Die lokale "verdeckt" in diesem 
Fall die globale.

Oliver

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Martin schrieb:
> ist das so mit dem AVR-GCC erlaubt?

Nicht nur in dem, es geht mit jedem C-Compiler und zwar auch mit 
Funktionen.

von Martin (Gast)


Lesenswert?

OK, es hat etwas gebraucht aber ich bin doch noch auf den Hund gekommen 
wie ich's testen kann. So ne Pause wirkt doch Wunder!
Nur entspricht mein Ergebnis nicht dem, was ich aus deiner Antwort 
erwartet hätte:

Der Test
 main.c
1
#include <avr/io.h>
2
#include "extern.h"
3
4
void reset( void );
5
6
int main( void )
7
{
8
  while(1)
9
  {
10
    extern uint8_t var;
11
    if( var != 0 )
12
      reset();
13
    foo();
14
  }
15
  return 0;
16
}
17
18
void reset( void )
19
{
20
  extern uint8_t var;
21
  var = 0;
22
}

 extern.h
1
void foo( void );

 extern.c
1
#include "extern.h"
2
#include <avr/io.h>
3
4
uint8_t var = 0;
5
6
void foo( void )
7
{
8
  var++;
9
}

Das Ergebnis
 .lss-file
1
0000005c <main>:
2
int main( void )
3
{
4
  while(1)
5
  {
6
    extern uint8_t var;
7
    if( var != 0 )
8
  5c:  80 91 00 01   lds  r24, 0x0100
9
  60:  88 23         and  r24, r24
10
  62:  11 f0         breq  .+4        ; 0x68 <main+0xc>
11
}
12
13
void reset( void )
14
{
15
  extern uint8_t var;
16
  var = 0;
17
  64:  10 92 00 01   sts  0x0100, r1
18
  while(1)
19
  {
20
    extern uint8_t var;
21
    if( var != 0 )
22
      reset();
23
    foo();
24
  68:  01 d0         rcall  .+2        ; 0x6c <foo>
25
  6a:  f8 cf         rjmp  .-16       ; 0x5c <main>
26
27
0000006c <foo>:
28
29
uint8_t var = 0;
30
31
void foo( void )
32
{
33
  var++;
34
  6c:  80 91 00 01   lds  r24, 0x0100
35
  70:  8f 5f         subi  r24, 0xFF  ; 255
36
  72:  80 93 00 01   sts  0x0100, r24
37
}
38
  76:  08 95         ret

... ist das jetzt Verlässlich?

von Martin (Gast)


Angehängte Dateien:

Lesenswert?

Bissl unübersichtlich, ich häng die Files nochmal an

Danke
Gruß Martin

von (prx) A. K. (prx)


Lesenswert?

Martin schrieb:
> Nur entspricht mein Ergebnis nicht dem, was ich aus deiner Antwort
> erwartet hätte:

Kommt drauf an, wessen Antwort du meinst.
Johann liegt richtig, Oliver nicht.

von (prx) A. K. (prx)


Lesenswert?

Oliver schrieb:
> (ob extern oder nicht, ist dabei egal).

Keineswegs. Es ist der entscheidende Unterschied.

von Martin (Gast)


Lesenswert?

A. K. schrieb:
> Johann liegt richtig, Oliver nicht.

Johann habe ich vollkommen übersehen, da war ich wohl selbst schon im 
schreiben...

A. K. schrieb:
> Oliver schrieb:
>> (ob extern oder nicht, ist dabei egal).
>
> Keineswegs. Es ist der entscheidende Unterschied.

du meinst, dass 'extern' der entscheidende Unterschied ist, verstehe ich 
das richtig?

von (prx) A. K. (prx)


Lesenswert?

Martin schrieb:
> du meinst, dass 'extern' der entscheidende Unterschied ist, verstehe ich
> das richtig?

Ja.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Martin schrieb:
> du meinst, dass 'extern' der entscheidende Unterschied ist, verstehe ich
> das richtig?

Ja, denn ohne extern wäre es die Definition einer lokalen Variable, 
nicht die Deklaration einer extern.

Dein Disassembly von oben entspricht nicht dem Quellcode, irdendwo hast 
da gemogelt!

von (prx) A. K. (prx)


Lesenswert?

Johann L. schrieb:
> Dein Disassembly von oben entspricht nicht dem Quellcode, irdendwo hast
> da gemogelt!

Inwiefern? Bei mir kommt exakt ebendieser Asm-Code raus (4.7.2).

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Da: Beitrag "Re: globale Variable von anderem File lokal extern deklarieren möglich?"

reset() hat im Disassembly ein while(1), in der Quelle jedoch nicht!

von (prx) A. K. (prx)


Lesenswert?

Johann L. schrieb:
> reset() hat im Disassembly ein while(1), in der Quelle jedoch nicht!

Ist das while in main. Ein Schmutzeffekt des Disassemblers beim Versuch, 
für Code mit Inlining den Quellcode irgendwie unterzubringen.

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.