www.mikrocontroller.net

Forum: Compiler & IDEs Globale Variablen brauchen mehr Speicher als lokale?


Autor: G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tag, ich habe hier ein Programm, bei dem mir etwas aufgefallen ist. Da 
sind 4 Funktionen drin. In jeder Funktion wird eine lokale temp Variable 
angelegt. Ich habe gedacht, eine globale Variable wäre hier günstige, 
aber der erzeugte Code ist deutlich größer.

Wie kommt das?

G.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann man so allgemein nicht sagen.

IdR sind lokale auto-Variablen günstiger, ja. Aber wenn es zu viele 
werden, dann muss gcc einen Frame für die ganzen lokalen Variablen 
anlegen, und das kostet Code (und Laufzeit).

Ausserdem ist es ungünstig, auto-Variablen anzulegen, die nicht in 
Registern gehalten werden können. Das sind zB Variablen mit "krummer" 
Größe.

Ebenfalls nicht prickelnd ist es, wenn man die Adresse einer 
auto-Variablen braucht und der Compiler die Adressberechnung nicht 
wegoptimieren kann.

Bei globalen Variablen kann es günstig sein, sie in temporäre lokale 
Variablen zu kopieren um die Manipulationen zu machen.

Aber es ist immer abhängig vom Compiler, vom Code und der 
Zielarchitektur was "gut" und was "schlecht" ist. Nicht alles wird vom 
Compiler optimal umgesetzt; den optimalen Compiler gibt es eben noch 
nicht.

Autor: G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
avr-gcc, hatte ich vergessen zu erwähnen.

Hm, stimmt, so ne temporäre Variable im Register wäre nicht verkehrt. 
Wählt der Compiler automatisch ein entsprechendes Register?

Und wie ist das mit Interrupts und lokalen Variablen? Geht das 
problemlos?

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
G. wrote:
> Hm, stimmt, so ne temporäre Variable im Register wäre nicht verkehrt.
> Wählt der Compiler automatisch ein entsprechendes Register?
Ja und nein. Mit dem 'register'-Schlüsselwort kannst du dem Compiler 
empfehlen, die Variable in einem Register zu halten. Ob er das dann 
auch macht, und wenn ja, welches Register er benutzt, bleibt ihm ganz 
alleine überlassen.
Beim GCC kann man mit dem ASM-Dingen eine Variable fest an ein 
selbstgewähltes Register binden, näheres dazu im Tutorial.

> Und wie ist das mit Interrupts und lokalen Variablen? Geht das
> problemlos?
Ja, geht. Die liegen ja im Frame des Aufrufs, und das wird für jeden 
Aufruf neu angelegt und danach wieder freigegeben.

Autor: Günter R. (galileo14)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
G. wrote:
> Und wie ist das mit Interrupts und lokalen Variablen? Geht das
> problemlos?

Das kommt darauf an, was du machen willst; wenn sich die Tätigkeit der 
Interrupt-Funktion nur lokal auswirkt, sind lokale Variablen das beste. 
Wenn Du allerdings Ergebnisse nach "draußen" exportieren willst (wie 
z.B. empfangene UART-Zeichen oder Zähler-Erhöhungen oder im Interrupt 
gemessene Spannungen), verwendest Du globale Variablen. Dabei dann ggf. 
"volatile" nicht vergessen!

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sven Pauli schrob:
> G. wrote:
>> Hm, stimmt, so ne temporäre Variable im Register wäre nicht verkehrt.
>> Wählt der Compiler automatisch ein entsprechendes Register?
> Ja und nein. Mit dem 'register'-Schlüsselwort kannst du dem Compiler
> empfehlen, die Variable in einem Register zu halten. Ob er das dann
> auch macht, und wenn ja, welches Register er benutzt, bleibt ihm ganz
> alleine überlassen.

register und atuo haben heutzutage keinen Effekt mehr, zumindest 
nicht be gcc. Der weiß was gut ist... Lokale Variablen versucht er in 
GPRs zu halten.

> Beim GCC kann man mit dem ASM-Dingen eine Variable fest an ein
> selbstgewähltes Register binden, näheres dazu im Tutorial.

Wovon aber abzuraten ist, wenn man nicht genau weiß was das für 
Nebeneffekte hat bzw. haben kann!

Günter R. schrob:
> Wenn Du allerdings Ergebnisse nach "draußen" exportieren willst (wie
> z.B. empfangene UART-Zeichen oder Zähler-Erhöhungen oder im Interrupt
> gemessene Spannungen), verwendest Du globale Variablen. Dabei dann ggf.
> "volatile" nicht vergessen!

...und daß der Zugriff ggf. atomar sein muß um Race-Conditions etc. zu 
vermeiden.

Autor: G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, dann lass ich es bei normalen lokalen Variablen. Danke für die Hilfe

Autor: G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe dazu gerade etwas interessantes gefunden.
http://www.wiki.elektronik-projekt.de/mikrocontrol...

Da steht alles

Autor: Günter R. (galileo14)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
G. wrote:
> 
http://www.wiki.elektronik-projekt.de/mikrocontrol...
>
> Da steht alles

Der Ersteller dieses Wikis sollte mal ein Rechtschreibprogramm über 
seine Texte laufen lassen ...

Autor: kater (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Ersteller dieses Wikis sollte mal ein Rechtschreibprogramm über
seine Texte laufen lassen ...

Kritik angekommen und akzeptiert und Text in Bearbeitung.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
G. schrob:
>
http://www.wiki.elektronik-projekt.de/mikrocontrol...
>
> Da steht alles

...ganz falsch.

Günter R. schrieb:
>> Der Ersteller dieses Wikis sollte mal ein Rechtschreibprogramm über
>> seine Texte laufen lassen ...

kater schrieb:
> Kritik angekommen und akzeptiert und Text in Bearbeitung.

Ojeojemineoje bei so vielen sachlichen und inhaltlichen Fehlern lohnt es 
sich echt nicht, die Orthografie aufzupolieren!

Am besten ganz in die Tonne kloppen!

Autor: G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Da steht alles

>...ganz falsch.
>Ojeojemineoje bei so vielen sachlichen und inhaltlichen Fehlern

Erklärst du uns auch was da so falsch ist, von den offensichtlichen 
Rechtschreibfehlern abgesehen?

Schließlich stammt der Inhalt aus einer AppNote von Atmel. Es kann 
höchstens sein das es nicht genau so auf den avr-gcc zutrifft.

Wenn sich Übersetzungsfehler eingeschlichen haben könntest du sie 
vielleicht einfach mal korrigieren oder zumindest darauf hinweisen statt 
nur zu maulen. Ich finde es echt zum Kotzen. Da macht sich jemand die 
Mühe um sowas zu erstellen und wenn es mal nicht ganz passt wird gemault 
statt das man hilft es zu verbessern.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
G. wrote:

> Erklärst du uns auch was da so falsch ist, von den offensichtlichen
> Rechtschreibfehlern abgesehen?

"Die Pointer werden auch benutzt, um auf den Flash Speicher zuzugreifen. 
Der Speicher kann auch direkt adressiert werden. Das gibt Zugriff auf 
den gesamten Speicher mit einer 2-Word Instruktion."

Trifft auf avr-gcc nicht zu, dort geht Zugriff auf Flash nur über 
Funktionen. Der resultierende Code ist zwar ähnlich, aber die 
Programmierung viel unmständlicher.

"Nach dem Einschalten oder einem Reset muss der Stack Pointer 
initialisiert werden, bevor irgendeine Funktion aufgerufen werden kann."

Nur bei älteren AVR-Modellen. Und was hat das eigentlich mit dem Thema 
zu tun? Das ist Sache des Compilers bzw. dessen Laufzeitcode/Library und 
nicht des Programmierers.

"Das SRAM ist für globale Variablen reserviert und kann für nichts 
anderes verwendet werden."

Der Stack in dem sich u.A. die lokalen Variablen befinden liegt auch 
dort. Besser: Das RAM kann nur für Daten, nicht aber für Code verwendet 
werden.

"Lokale Variablen werden bevorzugt in den Registern gespeichert wenn sie 
deklariert werden."

Unverständlich. Es gibt keine undeklarierten lokalen Variablen.

"Eine lokale statische Variable wird in ein Register beim Start der 
Funktion geladen. Ist die Funktion zu Ende, wird die Variable zurück in 
das SRAM gespeichert. Statische Variablen sind darum effizienter als 
globale Variablen, wenn sie mehr als einmal in der Funktion benutzt 
werden."

Es kann sein, dass der Compiler den Code so optimiert. Es kann 
allerdings auch sein, dass er es nicht macht und damit genauso umgeht 
wie mit globalen Variablen.

"Bis zu zwei Parameter von einfachen Variablen (char,int, long, float, 
double) können zwischen den Funktionen über die Register R16-R23 
getauscht werden."

Dies skizziert wohl das Registermodell eines bestimmten Compilers. 
avr-gcc arbeitet anders und es werden auch mehr als 2 Parameter in 
Registern übergeben.

"Wenn globale Variablen benötigt werden, sollten sie wenn immer es 
passend ist in Strukturen abgelegt werden. So ist es dem Compiler 
möglich sie direkt zu adressieren."

Abhängig vom verwendeten Compiler und keineswegs allgemein gültig.

Autor: G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank, wenigstens einer der mithilft. Ich werde das mal 
weitergeben.

Aber wenn ich das so lese gibt es für die meisten Diskrepanzen 2 Gründe: 
Das Alter der AVR035, die ist vom Januar 2004, und die Tatsache, das sie 
nicht für den avr gcc geschrieben wurde. Gab es den 2004 überhaupt 
schon?

Jedenfalls steht in dem Artikel, das es eine freie und nicht 
vollständige Übersetzung der AVR035 ist. Wenn ich das im Original 
richtig gelesen habe fehlt zum Beispiel der Teil mit dem Eeprom

Wie auch immer, vielleicht kann der Autor ja eine Anpassung an den gcc 
und das Jahr 2009 vornehmen

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was dort speziell in Bezug auf avr-gcc fehlt: Es sollten bei kleinen und 
mittleren Funktionen möglichst nur skalare Daten als lokale Variablen 
mit der impliziten Speicherklasse "auto" verwendet werden, und diese 
sollten nie indirekt genutzt werden (auch nicht als indirekter Parameter 
wie &var). Ansonsten muss der Compiler recht aufwendig einen 
vollständigen Stack-Frame erzeugen, und auch die Adresse einer solchen 
Variblen wird deutlich umständlicher ermittelt als bei statisch 
adressierten Variablen. Irgendwelche Puffer-Arrays und Stringspeicher 
sind als also lokale "static"s effizienter.

Autor: G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Es sollten bei kleinen und mittleren Funktionen möglichst nur skalare Daten
>als lokale Variablen mit der impliziten Speicherklasse "auto" verwendet
>werden...

Ohweh, da bin ich nicht Freak genug um das zu verstehen ;)

Wird das irgendwo erklärt so das auch ich das verstehen kann? Am besten 
auf deutsch. Ich bin Ü40 und meine Englischkenntnisse sind etwas 
bescheiden.

Autor: kater (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es freut mich Leute kennenzulernen die mehr von Compiler verstehen als 
ich. Für mein schlechtes Englisch und Deutsch muss ich mich 
entschuldigen, ich hatte den Text nie korrektur gelesen, da ich ihn nie 
veröffentlichen wollte. Ich habe ihn aus reinen privaten 
Interessengründen in das deutsch übersetzt.
Auch habe ich nie gesagt, dass es auf den avr-gcc zutrifft, noch das es 
richtig oder aktuell ist. Es ist eine Übersetzung des AVR App Note 35. 
Beschwerden gehen an Atmel.

Wenn sich die Profis hier aber mal zusammen setzen würden um einen 
aktuellen ähnlichen Text zu entwerfen, würde mich das sehr freuen. Mich 
interesiert diese Compilerdinge sehr, sonst hätte ich mir auch nie die 
Mühe gemacht etwas zu übersetzen.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
G. wrote:

> Ohweh, da bin ich nicht Freak genug um das zu verstehen ;)

Lokale Daten können "static" oder "auto" sein ("register" ist etwas aus 
der Mode gekommen). Steht nichts dabei, dann sind lokale Daten "auto", 
das sind also die normalen.

Skalare Daten sind das Gegenteil von zusammengesetzten Datentypen wie 
Arrays und struct/union. Also einfache Daten vom Typ "int", "char", 
"float", ..., sowie Zeiger und auch "enum". Also das was in Register 
passt.

Läuft letztlich darauf hinaus, dass bei avr-gcc nur solche Daten lokal 
ohne "static" verwendet werden sollten, die der Compiler in Register 
legt. Wenn er das nicht mehr kann, dann wird der Code der Funktion 
deutlich aufwendiger.

> Ich bin Ü40

Ich auch. Das kann ich also als Entschuldigung nicht gelten lassen ;-).

Autor: G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Erläuterung.

>Ich auch. Das kann ich also als Entschuldigung nicht gelten lassen ;-).

Nach dem Schulenglisch hatte ich nicht mehr viel damit zu tun. Im 
Nachhinein ärgert es mich.

Deshalb freue ich mich immer, wenn sich Leute die Mühe machen sowas in 
deutsch zu schreiben

Autor: G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, entschuldigt wenn ich nerven sollte, aber ich möchte versuchen das 
richtig zu verstehen. Ich habe gerade ein wenig gegoogelt und möchte 
das gelesene nur nochmal absichern.

Wenn ich eine Variable, egal welchen Typs, außerhalb eines Blocks oder 
einer Funktion ohne Zusatzangaben deklariere, wird sie im SRAM abgelegt. 
Wenn sie verwendet wird muss sie jedes mal in ein Register kopiert 
werden, oder zumindest ein Zeiger initialisiert werden. In dem Fall ist 
es eine globale static Variable.

Wenn ich eine skalare Variable, also Char, Int usw, innerhalb einer 
Funktion ohne Zusatz deklariere wird sie, sofern möglich, in einem 
Register abgelegt. Deshalb ist der Code kompakter (um auf die 
ursprüngliche Frage zurückzukommen).

Wenn ich ein Array/String innerhalb einer Funktion deklarieren muss ich 
sie static deklarieren wodurch sie letztendlich zu einer globalen 
Variable wird die zur gesamten Laufzeit im SRAM liegt

Ich hoffe, ich habe das halbwegs richtig verstanden und wiedergegeben.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
G. wrote:

> Wenn ich eine Variable, egal welchen Typs, außerhalb eines Blocks oder
> einer Funktion ohne Zusatzangaben deklariere, wird sie im SRAM abgelegt.
> Wenn sie verwendet wird muss sie jedes mal in ein Register kopiert
> werden, oder zumindest ein Zeiger initialisiert werden. In dem Fall ist
> es eine globale static Variable.

Was du mit den Zeiger meinst weiss ich nicht, aber der Rest stimmt. Es 
sein denn die Variablen wird so deklariert, dass sie im Flash oder 
EEPROM landet.

> Wenn ich eine skalare Variable, also Char, Int usw, innerhalb einer
> Funktion ohne Zusatz deklariere wird sie, sofern möglich, in einem
> Register abgelegt. Deshalb ist der Code kompakter (um auf die
> ursprüngliche Frage zurückzukommen).

Korrekt.

> Wenn ich ein Array/String innerhalb einer Funktion deklarieren muss ich
> sie static deklarieren wodurch sie letztendlich zu einer globalen
> Variable wird die zur gesamten Laufzeit im SRAM liegt

Du musst nicht, du kannst. Bei avr-gcc führt das zu kürzerem Code, hat 
aber ggf. höheren RAM-Verbrauch zur Folge. Wenn das RAM knapp ist, Flash 
aber nicht, dann ist "static" kein Vorteil.

Wenn man beispielsweise diverse Funktionen hat, die alle einen 
temporären Stringpuffer verwenden, dann kann es in diesem Sinne auch 
nützlich sein, für alle den gleichen statischen Puffer zu verwenden.

Autor: G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Was du mit den Zeiger meinst weiss ich nicht...
Naja, wenn man ein Array oder so etwas hat wird ja nicht jedesmal das 
komplette Array an eine Funktion übergeben sondern nur ein Zeiger oder 
eine Referenz.

>Du musst nicht, du kannst. Bei avr-gcc führt das zu kürzerem Code, hat
>aber ggf. höheren RAM-Verbrauch zur Folge. Wenn das RAM knapp ist, Flash
>aber nicht, dann ist "static" kein Vorteil.

Wenn es Konstanten im Flash sind muss man offensichtlich static davor 
setzen. Ich zitiere aus dem Tutorial dieser Seite:

>Deklarationen von Variablen im Flash-Speicher werden durch das "Attribut" 
>PROGMEM ergänzt. Lokale Variablen (eigentlich Konstanten) innerhalb von 
>Funktionen können ebenfalls im Programmspeicher abgelegt werden. Dazu ist >bei 
der Definition jedoch ein static voranzustellen, da solche "Variablen" >nicht auf 
dem Stack bzw. (bei Optimierung) in Registern verwaltet werden >können. Der 
Compiler "wirft" eine Warnung falls static fehlt.

Hm, ich hoffe, eines Tages verstehe ich die Funktion von static, 
volatile,  extern usw mal richtig. Halbwissen ist manchmal 
gefährlicher als gar nichts wissen

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
G. wrote:
> Ok, entschuldigt wenn ich nerven sollte, aber ich möchte versuchen das
> richtig zu verstehen. Ich habe gerade ein wenig gegoogelt und möchte
> das gelesene nur nochmal absichern.

Das Thema ist recht komplex.

Nach meiner unspezifischen Kritik an dem oben verlinkten Artikel geht's 
also ins Eingemachte!

Zum Thema Optimierungen kann man keine allgemeingültigen Tipps geben:
Formal gesprochen bildet ein Compiler eine C-Quelle auf eine 
Assembler-Quelle oder eine Binärdatei ab.

Den erzeugten Code kann er beliebig wählen sofern er im Rahmen seiner 
Spezifikation die Semantik unverändert lässt .

Ein Compiler ist nicht dazu "verpflichtet", kurzen oder schnellen Code 
zu erzeugen oder überflüssige Instruktionen wegzulassen.

Zunächst ist die Codegüte bei gleichbleibender Maschine, für die erzeugt 
werden soll, abhängig vom
* verwendeten Compiler (also auch von seiner Version)
* seinen Einstellungen (Schalter, Optionen, ...)
* wieviel Wissen er über die Quelle hat
* wie die Quelle hingeschrieben ist

Dabei will ich immer davon ausgehen, daß mehrere im folgenden zu 
vergleichende Quellen für den Progammierer semantisch äquivalent sind. 
Der Programmierer hat idR das meiste Wissen über die Quelle, etwa 
darüber, ob eine extern aufgerufene Funktion globale Variablen verändert 
oder nicht, und wenn ja, welche.

Weiterhin will ich davon ausgehen, daß sowohl der Befehlssatz und die 
Möglichkeiten der Maschine bekannt sind als auch die Sprache C und ihre 
Konstrukte und Konzepte.

Für AVR ist dabei in erster Linie bedeutsam:
* Wie mächtig sind die einzelnen Register?
* Welche Adressierungsarten kennt AVR?
  Wie teuer sind sie im Hinblick auf Raum und Zeit?

Da der Compiler, um dem es im Forum i.W. geht, avr-gcc ist, beziehe 
ich mich im folgenden auf ihn. Hier sind wichtig:
* Wie verwendet der Compiler die einzelnen internen Register (GPRs)?
  Etwa zur 
  - Argumentübergabe bei Funktionsaufrufen
  - Zugriff auf Daten im Flash
  - Zugriff auf den Stack
* Welche Optimierungsstrategiern gibt es (im groben) und welche 
  könnte er vielleicht anwenden?
* Wie stellt man den Compiler richtig ein? Welche Schalter, etc?
  Allgemein: wie sollte man den Compiler aufrufen?
* Was kann er mit welchem Wissen anfangen? Etwa 
  - wird eine Funktion nur in einem Modul verwendet?
  - wird eine Funktion (statisch) nur 1x aufgerufen
  - hat ein eine Variable einen zur Compilerzeit oder zur Linkzeit
    bekannten Wert?
* Wann ist es günstig, dem Compiler Informationen zu geben, und wann, 
  ihm Informationen vorzuenthalten? Wie stellt man das überhaupt an?

Was die Sprache C betrifft:
* Was genau sind die Unterschiede zwischen den einzelnen Speicherklassen?
* Was genau ist und was bewirken Qualifier wie volatile und const?
* Was genau sind die Unterschiede zwischen globalen und lokalen Variablen?
* Was genau bedeutet ein Funktionsaufruf?
* Was genau passiert bei Adressbildung einer Variablen?
* Was genau passiert bei Dereferenzierung eines Zeigers?

Gerade über die C-Punkte besteht oft große Unklarheit.

Dazu mache man sich die Unterschiede folgender Variablendefinitionen und 
-deklarationen klar (hier im Gegensatz zu Code-Conventionen alle in 
Großbuchstaben):
int A;
int A1 = 1;
static int B;
static int B1 = 1;
extern int C;

void foo (int I, int * PI)
{
    int J;
    int J1 = 1;
    static int K;
    static int K1 = 1;
    extern int L;
}

und gleiches für Funktionen:
int E (int);
static int F (int);
extern int G (int);
int H (int, ...);

'n Haufen Holz :-) also, worüber man sich im voraus Klarheit verschaffen 
sollte...

Fortsetzung folgt

Johann

p.s.:

... falls Interesse besteht. (bevor ich mir hier den Wolf tippse... ;-))

Autor: MarkusB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, ich möchte mich jetzt auch mal zu Wort melden. Ist ja schließlich 
mein Wiki :)

Die Rechtschreibfehler habe ich größtenteils behoben. Mir ist selbst 
nicht aufgefallen, das da so viele Tippfehler drin waren. Was die Kritik 
angeht: wie schon erwähnt wurde handelt es sich um eine Übersetzung der 
AVR035. Die ist von 2004 und sicher für den IAR geschrieben. Das die 
Angaben mit dem avr-gcc von 2009 nicht unbedingt übereinstimmen kann man 
sich eigentlich denken.

@Johann L. und A. K.
Ich wäre interessiert daran mehr über den optimalen Einsatz den avr-gcc 
zu erfahren. Zum einen weil ich gerade aktiv viel damit arbeite und weil 
ich Zeitgleich im Wiki an einem Tutorial schreibe. Und ich möchte 
natürlich möglichst keinen Unsinn verzapfen.

Autor: Interessierter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@gjlayde

Super Thema, ich habe starkes Interesse an deinen Erklärungen.
Wäre auch etwas für einen Artikel.

Danke schön schonmal soweit dafür.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mein Teelöffel Senf :) zu folgendem Abschnitt:

  "Globale Variablen die außerhalb einer Funktion deklariert werden,
  werden dem SRAM zugeordnet. Das SRAM ist für globale Variablen
  reserviert und kann für nichts anderes verwendet werden. Das ist eine
  bedenkliche SRAM Verschwendung. Zu viele globale Variablen machen den
  Code weniger lesbar und schwer zu modifizieren."

Wie A. K. schon schrieb, wird das SRAM nicht nur für globale Variablen,
sondern noch für viele andere Dinge verwendet. Offensichtlich wurde das
Original

  "Global variables that are declared outside a function are assigned to
  an SRAM memory location. The SRAM location is reserved for the global
  variable and can not be used for other purposes, this is considered to
  be waste of valuable SRAM space. Too many global variables make the
  code less readable and hard to modify."

ungenau übersetzt. In dem Text ist die Rede von der der Variablen
zugeordneten "SRAM location" und nicht vom gesamten SRAM. Vielleicht
wäre folgende (freie und etwas ausführlichere) Übersetzung klarer:

  "Eine globale Variable, die außerhalb einer Funktion deklariert ist,
  wird an einer festen Speicherstelle im SRAM platziert. Diese
  Speicherstelle ist während des gesamten Programmlaufs von der globalen
  Variablen belegt und kann nicht zur Speicherung anderer Daten
  verwendet werden. Deswegen ist es eine Verschwendung wertvollen
  SRAM-Speicherplatzes, Variablen ohne triftigen Grund global zu machen.
  Darüber hinaus machen zu viele globale Variablen den Programmcode
  schwerer les- und änderbar."

Was den SRAM-Verbrauch betrifft, gilt das Geschriebene auch für alle mit
static deklarierten Variablen, da diese, wie der Name schon andeutet,
ebenfalls für den gesamten Programmlauf an einer festen Stelle im
SRAM liegen.

Autor: MarkusB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, ich werde es entsprechend ändern. Das sind so Feinheiten, die man 
leicht übersieht.

Ich habe inzwischen auch noch gelernt das das nicht nur für Funktionen 
sondern auch für Blöcke gilt. Man kann in einem Programm oder innerhalb 
einer Funktion mit {} einen abgegrenzten Block erstellen.

Autor: Micha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johann L. wrote
> ... falls Interesse besteht. (bevor ich mir hier den Wolf tippse... ;-))

Interesse besteht auf jeden Fall - und wahrscheinlich auch (dringender) 
Aufklärungsbedarf.

Autor: Dave F. (dave24)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sehr interessantes Thema!

Wie G. bereits schrieb:
> Halbwissen ist manchmal gefährlicher als gar nichts wissen

@Johann L.
Wäre an einer detaillierteren Ausführung ebenfalls äusserst 
interessiert.
Was die Sprache C betrifft, so bin ich mir über die von dir genannten 
Unterschiede sehr wohl bewusst, in Bezug auf den AVR habe ich aber immer 
wieder ein Verständnis-Problem.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.