Vorteile const-Variable

Hallo,

welche Vorteile habe ich, wenn ich eine Variable mit const initialisiere gegenüber einer Variablen die ich ohne den Zusatz const initialisiere?

Gruß Chris

Der Kompiler kann mit diesem Wissen besser optimieren. Im erzeugten Maschinencode kann statt eines Zugriffs auf den Speicher in dem sich der aktuelle Wert befindet einfach der schon zur compiletime als unveränderlich deklarierte Wert direkt zugewiesen werden. Boolsche Ausdrücke und davon abhängige bedingte Sprünge kann der kompiler durch feste absolute Sprünge ersetzen und ggf. code, der gar nicht zur ausführung gelangen kann, einfach weglassen.

Meines Wissen werden const-Variablen auch meist im Flash abgelegt und belegen keinen Platz im RAM.

Es gibt keine “const-variablen” - “const” macht eine Variable zu Einer Kontante - beides geht nicht :grin: </klugscheiß>

“const” benutzt man, wenn man innerhalb eines Programms oder einer Funktion einen festen, sich nicht mehr ändernden Wert setzt, der nicht zur Kompilierung zur Verfügung steht. Im Umkehrschluss werden Werte, wie z.B. Pins etc, die vor der Kompilierung bereits feststehen als define-Konstante deklariert.

Konstanten dienen meist nur der besseren Lesbarkeit.

Worin manifestiert sich die bessere Lesbarkeit einer Konstanten im Vergleich zu einer Variablen ?

Gruß Chris

[quote author=Marcus W link=topic=204268.msg1504592#msg1504592 date=1386869985] "const" benutzt man, wenn man innerhalb eines Programms oder einer Funktion einen festen, sich nicht mehr ändernden Wert setzt, der nicht zur Kompilierung zur Verfügung steht. Im Umkehrschluss werden Werte, wie z.B. Pins etc, die vor der Kompilierung bereits feststehen als define-Konstante deklariert. [/quote] const ist meistens besser als #define. Jedenfalls für einfache Konstanten (im Gegensatz zu komplexen Makros).

define hat größtenteils historische Gründe. Das geht auf den Unterschied zwischen C und C++ zurück. Ursprünglich gab es in C kein const. Das wurde erst in C89 aus C++ übernommen und hat in ANSI-C auch nicht die gleiche Bedeutung wie in C++! In ANSI-C heißt const nur, dass die Variable "read-only" ist. Es ist keine richtige Konstante wie in C++. In C gibt es außerdem Probleme beim Linken wenn man const in Headern verwendet.

define hat den Nachteil, dass es vor dem kompilieren ausgeführt ist. Es ist einfach eine Textersetzung auf Token Basis. Alle Tokens die gleich der Konstante sind (egal ob Text, Variablen oder sogar Methoden-Namen) werden durch den Wert ersetzt. Das ist ein Grund weshalb man Konstanten besser in Großbuchstaben schreibt. Bei const greifen die Typ-Prüfungen des Compilers. const hält sich außerdem an Scope Regeln.

Manche Leute verwenden in C deshalb auch gerne enums für einzelne Konstanten.

Meines Wissen werden const-Variablen auch meist im Flash abgelegt und belegen keinen Platz im RAM.

Genau so habe ich das auch bisher verstanden - zum Sram sparen.

Stimmt das nun oder nicht ?

Laut dem hier ja: http://www.embedded.com/electronics-blogs/programming-pointers/4023858/Symbolic-Constants http://www.embedded.com/electronics-blogs/programming-pointers/4023879/Enumeration-Constants-vs-Constant-Objects

Zumindest in den meisten Fällen. Es hängt vom Compiler ab und was genau man mit den Dingern macht.

Und laut dem hier, gilt das auch für den Arduino (dritte Antwort): http://www.reddit.com/r/arduino/comments/1gkq8b/

Wobei man für Arrays wohl PROGMEM verwenden muss. Ich nehme mal an const Arrays sind auch nur read-only, da sich der Index i.d.R. ständig ändert und der Compiler daher nicht einfach die Werte ersetzen kann.

Wie gesagt muss man dabei aufpassen ob man über C oder C++ liest, da da const da zwei völlig verschiedene Dinge sind. In C++ wird heutzutage von #define in den meisten Fällen abgeraten. Selbst für Makros gibt es statt dessen inline Funktionen.

Kurz zusammengefasst für einen Anfänger wie mich:

Benötige ich Variablen, deren Wert sich nicht ändern, macht es Sinn diese aus Performancegründen gleich als Konstanten zu initialisieren.

Gruß Chris

Beim von der Arduino IDE verwendeten AVRGCC Compiler würde ich fixe werte wie etwa "LEDPIN" etc z.B. durch

#define LEDPIN 13

definieren. Das trägt dann zur Lesbarkeit bei, indem der Mensch an allen Stellen im Code "LEDPIN" lesen kann und der Compiler automatisch "13" daraus macht.

"const" Konstanten verwendet man, wenn sich ein zur Laufzeit generierter Wert nicht mehr ändert, etwa wenn du Konstante Werte in einer Funktion oder Lib benötigst. Diese werden dann normalerweise im Flash und nicht im RAM ausgelagert, da nicht schreibend darauf zugegriffen werden muss - du sparst dir etwas RAM - bei einem "const byte" z.B. 8Bit/1Byte.

Wenn ein Wert erst zur Laufzeit generiert wird kann er auch nicht im Flash landen :) Das geht nur wenn der Wert beim Compilieren fest steht. const verhält sich dann meistens auch nicht anders als #define. 100%ig garantiert ist es aber nicht.

Was du meinst ist z.B. Pointer-Parameter von Methoden als const deklarieren. Damit stellt man sicher, dass die Methode den übergebenen Wert nicht verändern kann.

Serenifly: Was du meinst ist z.B. Pointer-Parameter von Methoden als const deklarieren. Damit stellt man sicher, dass die Methode den übergebenen Wert nicht verändern kann.

Japp, so in etwa. Im Endeffekt ist es eh nur eine Voroptimierung für den Compiler - dem man in einigen Situationen eben zum Glück zwingen muss. Das gegenläufige Beispiel wäre glaub ich "volatile"

Ja, volatile sagt dem Compiler dass er gefälligst nichts optimieren soll.

Bei Interrupt Service Routinen kann der Compiler nicht feststellen wie diese aufgerufen werden. Er kommt also oft auf die Idee dass die Variable nie beschrieben wird und optimiert sie weg.

Statt

#define LEDPIN 13

könnte Marcus auch

const byte LEDPIN=13;

schreiben.

Überall wo du sinnvollerweise LEDPIN verwendest, passen beide Deklarationen und ergeben den gleichen compilierten Sketch. Die zweite Deklaration hilft dem Compiler und stellt sicher, dass du LEDPIN nur dort verwenden kannst, wo ein konstanter Wert vom Datentype byte verwendet werden darf. Im #define - Fall wird einfach vor dem Compilieren überall wo LEDPIN steht, dies durch 13 ersetzt.

Als sinnloses Beispiel eines schlechten #define

#define NEGATIV -1            // sollte normalerweise besser so heissen :   #define NEGATIV (-1) 

int rueckwaerts = 99;
void test()  {
   if ( rueckwaerts == NEGATIV )
      rueckwaerts = 100 + (NEGATIV);    // wofür wohl die Klammern sind ? ;)
   else  rueckwaerts = rueckwaerts NEGATIV;  // das geht leider, ohne dass der Compiler meckert
}

Macros sind eine ähnliche Geschichte:

#define INVERS(x)  ( 1.0/(x) )

heisst normalerweise besser

inline float INVERS(float x) { return 1.0 / x; }

weil da dem Compiler die Datentypen klar festgelegt sind !