Guten Morgen zusammen!
ich möchte gerne etwas Ordnung in meine Konstanten bringen.
Wenn ich z.B. so was anstatt ungeordneter const-Werte oder #defines
mache:
1
conststructgame
2
{
3
constuint8_tv_max;
4
constuint8_ta_max;
5
constuint8_tsize_x;
6
constuint8_tsize_y;
7
//...
8
};
Ist es so, dass game.size_x als Wert zum compilieren genommen wird und
keine Laufzeit kostet?
danke Euch!
Ich finde es übersichtlicher so. Das kann ich für mich wesentlich besser
strukturieren und lesen.
Aber weißt du auch was zu meiner Frage zu sagen? Ist es auch wirklich
vom Ergebnis äquivalent?
Ich glaub was du eigentlich fragen willst ist:
"Ist es so, dass game.size_x als Wert im Flash landet und nicht im RAM?"
Und die Antwort ist ja. Ich glaub du solltest aber generell ein wenig
über den const-qualifier lesen.
Bomwollen schrieb:> Aber weißt du auch was zu meiner Frage zu sagen? Ist es auch wirklich> vom Ergebnis äquivalent?
Das hängt vom Compiler ab. Wenn er will, kann er dein struct-Konstrukt
so weit optimieren, dass derselbe Code rauskommt. Muss er aber nicht.
gcc macht's so. Allerdings nur, wenn erstens die Optimierung auf
mindestens -O1 eingestellt ist und 2. er bei jeder Verwendung die
gesamte struct inclusive ihrer Initialisierung zu sehen bekommt.
Ich halte die Vorgehensweise für keine gute Idee.
Ich möchte eigentlich nicht nur wissen, ob das im Flash landet, sondern
ob der compiler den constanten Wert auch benutzt.
Wenn das nur im Flash landet und dann bei Benutzung der Wert aus dem
Flash geholt würde, dann dauert das ja.
Markus F. schrieb:> Das hängt vom Compiler ab.
Da der Compiler aber bekannt ist, (avr-gcc), wird er das wie gewünscht
optimieren (wenn der Code soweit ergänzt wird, daß er kompilierbar
wird).
Ich würde dafür allerdings einen namespace verwenden.
Bomwollen schrieb:> "Ich halte die Vorgehensweise für keine gute Idee.">> Also du würdest eher #defines benutzen und versuchen die so gut es geht> zu sortieren?
Wenn dein Arduino-Universum constexpr beherrscht (und Du auch), ist das
- wie oben erwähnt - wahrscheinlich die beste Idee.
Oliver S. schrieb:> Da der Compiler aber bekannt ist, (avr-gcc), wird er das wie gewünscht
ist er das? Wenn ich mich recht erinnere, gibt's Arduino in allen
möglichen Geschmacksrichtungen und längst nicht mehr nur für AVR.
Bomwollen schrieb:> Ich möchte eigentlich nicht nur wissen, ob das im Flash landet, sondern> ob der compiler den constanten Wert auch benutzt.> Wenn das nur im Flash landet und dann bei Benutzung der Wert aus dem> Flash geholt würde, dann dauert das ja.
Das hängt sehr stark von der von dir verwendeten Architektur ab, die
unter "Arduino" ja mittlerweile sehr bunt ist. Alle mir gängigen
modernen Compiler erzeugen für Literals optimalen Code.
Kann die Konstante in einen Maschinenbefehl codiert werden, dann wird
dies auch geschehn (inkl. teils recht lustiger Tricks wie negieren
usw.). Kann sie das nicht, dann bleibt dem Compiler nichts anderes übrig
als sie im Flash abzulegen.
Ob du nun
Bomwollen schrieb:> Ist es so, dass game.size_x als Wert zum compilieren genommen wird und> keine Laufzeit kostet?
In C wird const in Static Storage spätestens zur Load-Time bestimmt.
In C++ kann Static Storage const auch zur Laufzeit geändert werden, zum
Beispiel kann der Compiler Startup-Code erzeugen, der einen const erst
zur Laufzeit initialisiert, etwa in einem statischen Constructor wie in
1
externintvolatilev;
2
constinti=v;// Initialisierung zur Laufzeit
Wie es in deinem Falle liegt hängt ab vom Code und Optimierungen des
Compilers. Selbst wenn eine Initialisierung zur Load-Time möglich ist,
ist ein C++ Compile m.W. nicht dazu verpflichtet, dies auch wirklich zur
Load-Time auszuführen.
Erst mal danke für den Thread. Der hat mir sehr geholfen und kam ohne
traditionelles remgebolze aus! Obwohl ich noch Defizite habe. Zuletzt
konnte ich den Unterschied zwischen const und constexpr lernen. Danke!
Den Weg mit einem Namespace mag ich derzeit am liebsten.
Ein Ziel bei der C++ Entwicklung war, die überflüssigen #define
auszurotten.
Und darum geht es ean der stelle auch ohne.
Bomwollen schrieb:> const struct game> {> const uint8_t v_max;> const uint8_t a_max;> const uint8_t size_x;> const uint8_t size_y;> //...> };
Das ist auch eine schlechte Idee...
Wg. zusätzlicher Dereferenzierung
Mein Vorschlag:
Stropfe sie in einen anonymen Namespace.
So sind sie gruppiert und dennoch, ohne Klimmzüge oder zusätzliche
Dereferenzierung, erreichbar.
Patrick C. schrieb:> Was ist das nachteil von> #define GAME_V_MAX 23> #define GAME_A_MAX 5> (etc)
Fehlende Typeprüfung.
Kryptische Fehlermeldungen.
#define ist eine alte C Krankheit, welche nach C++ mit rüber geschleppt
wurde.
mittlerweile gibts schon recht gute Gegenmittel.
So muss heutzutagen nicht mehr jedes Programm unter der #Defineritis
leiden.
Wer ohne Not #define verwendet stellst sich selber ein Bein damit.
Und das wollen wir doch nicht!
Das ist hier gar nicht gefragt. Der Fragesteller will - wenn ich das
richtig verstehe - nur wissen, ob der Compiler seine Konstanten als
Literale verwendet (also insbesondere, ob Berechnungen mit den
Konstanten - wo möglich - bereits zur Compile-Zeit ausgeführt werden).
Meiner bescheidenen Meinung nach ist das nur mit constexpr einigermassen
gesichert.
Markus F. schrieb:> Meiner bescheidenen Meinung nach ist das nur mit constexpr einigermassen> gesichert.
Meiner bescheidenen Erfahrung nach macht der gcc das mit const sehr
zuverlässig.
Oliver
Markus F. schrieb:> Wenn dein Arduino-Universum constexpr beherrscht
Tut es, in den den neueren Versionen.
Aktuell ist wohl c++11 für den AVR Core
Und in der Hardware Definition, kann man das auch noch hochsetzen.
-std=gnu++14
Dann gehen auch Schleifen in constexpr usw.
Oliver S. schrieb:> Meiner bescheidenen Erfahrung nach macht der gcc das mit const sehr> zuverlässig.
Ja!
Für einfache Berechnungen ausreichend.