Hallo zusammen, gibt es für konstante Variablen in C (GCC) ähnliche Möglichkeiten, wie eine "weak"-Deklaration für Funktionen? Ich will in einer .c-Datei ein "Default" einer (struct)-Konfigurationsvariablen anlegen, die aber in einer anderen Datei überschreiben können. Im Notfall könnte ich aus der const-Variablen eine normale Variable machen, und eine Initialisierungsfunktion "weak" machen. Aber das wäre irgendwie unschön, zumal die const-Variable im Flash liegen kann. Alternativ kann ich die Initialisierungswerte in ein Präprozessor-Define packen und dann mit #ifdef prüfen, ob es nicht schon anderweitig vordefiniert wurde. Was mir daran nicht gefällt, ist dass der Header, in dem dieser vorrangige #define eventuell steht, auch #includieren muss, wenn er eigentlich gar nicht existieren müsste. Ausserdem wären dann die Deklaration des Structs und die Definition im #define getrennt, was auch eine nette Fehlerquelle ist. Oder geht es noch schöner? Viele Grüße W.T.
:
Gesperrt durch Moderator
In der Doku finde ich "weak" nur als Attribut für Funktionen. Natürlich habe ich es ausprobiert, ob es auch für Variablen geht, und ich diesen Teil nicht in der Doku finde. Deklariere ich eine Variable als "weak", z.B. so:
1 | const Menudimension_t Menudimension_messagebox __attribute__((weak)) = |
2 | {
|
3 | .Area = {0, 0, GFX_MAX_WIDTH_PX, GFX_MAX_HEIGHT_PX}, |
4 | .headheight = 2*GFX_MAX_HEIGHT_PX/3, |
5 | .scrollbarWidth = 0, |
6 | .margin = 0, |
7 | .textIndent = 2, |
8 | .cornerRadius = 0, |
9 | .headsep = -4, |
10 | };
|
so wird interessanterweise keine Compiler-Warnung erzeugt (GCC 5.1.0), aber aus dem Struct auch nur noch Unsinn ausgelesen. Wird dann eine zweite Definition des Structs erzeugt, also:
1 | const Menudimension_t Menudimension_messagebox __attribute__((weak)) = |
2 | {
|
3 | .Area = {0, 0, GFX_MAX_WIDTH_PX, GFX_MAX_HEIGHT_PX}, |
4 | .headheight = 2*GFX_MAX_HEIGHT_PX/3, |
5 | .scrollbarWidth = 0, |
6 | .margin = 0, |
7 | .textIndent = 2, |
8 | .cornerRadius = 0, |
9 | .headsep = -4, |
10 | };
|
11 | |
12 | const Menudimension_t Menudimension_messagebox = |
13 | {
|
14 | .Area = {0, 0, GFX_MAX_WIDTH_PX, GFX_MAX_HEIGHT_PX}, |
15 | .headheight = 2*GFX_MAX_HEIGHT_PX/3, |
16 | .scrollbarWidth = 0, |
17 | .margin = 0, |
18 | .textIndent = 2, |
19 | .cornerRadius = 0, |
20 | .headsep = -4, |
21 | };
|
kommt erwartungsgemäß der Compiler-Fehler "error: redefinition ....". Unterm Strich heisst das für mich: Der "weak"-Mechanismus scheint nur für Funktionen und nicht für Variablen/Konstanten zu funktionieren.
:
Bearbeitet durch User
Dein Forschergeist in Ehren, aber ist CONST als WEAK nicht ein konzeptueller Alptraum? Was spricht gegen eine normale Variable, die Du default (der CONST-Fall) füllst und bei Bedarf (und nachvollziehbar) abänderst? Könntest die Veränderung sogar über ein strukturelement (Z.B. .isDefaultInit) vermerken)
Mit libraries geht es vielleicht: wenn Du dein Default einzeln in eine lib legst, kannst Du im Projekt eine zweite Instanz definieren, die die erste "überschreibt". Natürlich nur metaphorisch, die aus der lib wird nicht dazugelinkt.
Walter T. schrieb: > Ich will in einer .c-Datei ein "Default" einer > (struct)-Konfigurationsvariablen anlegen, die aber in einer anderen > Datei überschreiben können. Mach das doch einfach. Und um das Default im .c ein #if. Dann brauchts im Header nur ein Schalter.
Das GCC-Manual sagt, dass weak auch mit Variablen geht. https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Variable-Attributes.html#Variable-Attributes Wenn ich dein Test oben richtig verstehe, hast du die gleiche Variable in einer Datei zweimal definiert? Das dürfte auch mit weak-Attribut ein Fehler sein (da das weak für den Linker ist, wenn ich mich nicht irre).
Stephan schrieb: > Dein Forschergeist in Ehren, aber ist CONST als WEAK nicht ein > konzeptueller Alptraum? > Was spricht gegen eine normale Variable, die Du default (der CONST-Fall) > füllst und bei Bedarf (und nachvollziehbar) abänderst? Könntest die > Veränderung sogar über ein strukturelement (Z.B. .isDefaultInit) > vermerken) Beides ist schwer nachvollziehbar, wenn man es versteckt. Const gibt aber etwas mehr Garatien, daher würde ich das persönlich eher vorziehen.
Ich bin zwar schon lange aus der Übung bzgl. c(++), aber wenn ich mir die Doku anschaue (Link im 2. Post) dann schreiben die: "The weak attribute causes the declaration to be emitted as a weak symbol rather than a global. This is primarily useful in defining library functions which can be overridden in user code, though it can also be used with non-function declarations. Weak symbols are supported for ELF targets, and also for a.out targets when using the GNU assembler and linker. " Was ich lese, dass es auch für Variablen geht. Das es nicht innerhalb einesC Files für ein ELF Target geht, sondern nur wenn man ein Symbol einer Lib oder einer Objektdatei ausserhalb "überschreiben" will. Was mir jetzt aber nicht klar ist. Wenn ich so eine Konstante benutze um in der lib in der sie definiert wurde andere Konstanten oder Werte zu definieren die der Compiler dann berechnet, wie wirkt sich das aus, wenn die Konstante dann redefiniert wird? Dann müsste der Linker ja auch die abhängigen Werte in der eingebundenen library neu berechnen.
:
Bearbeitet durch User
Udo S. schrieb: > Was mir jetzt aber nicht klar ist. Wenn ich so eine Konstante benutze um > in der lib in der sie definiert wurde andere Konstanten oder Werte zu > definieren die der Compiler dann berechnet, wie wirkt sich das aus, wenn > die Konstante dann redefiniert wird? Dann müsste der Linker ja auch die > abhängigen Werte in der eingebundenen library neu berechnen. Ich vermute, dass dann beide Definitionen gemischt werden. Also der Compiler immer die weake Definiton nutzt. Interessanterweise gibt es dieses Problem in C++ nicht, da es Unterschiede bei const in C vs. C++ gibt: https://stackoverflow.com/a/19492225 . In C++ gehen weak und const dann einfach nicht zusammen. Vll lohnt es sich weakref mal anzuschauen.
Stephan schrieb: > aber ist CONST als WEAK nicht ein konzeptueller Alptraum? Sehe ich auch so. Der Sinn darin, eine Variable als "const" zu deklarieren ist doch, dass der Compiler (und nicht erst der Linker) darauf Optimierungen anwenden kann, denn er muss nicht mehr davon ausgehen, dass sich deren Wert jenseits der (für ihn sichtbaren) Initialisierung nochmal ändert. Indem man eine Variable als weak deklariert, will man allerdings explizit, dass der exakte Wert erst nach dem Linken zur Verfügung steht. Damit darf der Compiler Zugriffe auf diese auf keinen Fall bereits zur Compilezeit optimieren.
Udo S. schrieb: > Wenn ich so eine Konstante benutze um in der lib in der sie definiert > wurde andere Konstanten oder Werte zu definieren die der Compiler dann > berechnet, wie wirkt sich das aus, wenn die Konstante dann redefiniert > wird? Der C-Compiler rechnet nicht mit Konstanten. Er bildet nicht Mal die Adressen.
Naja, Optimierung ist ja nicht alles. Entscheidender scheint mir, dass die Konstanten irgendwo im Code verstreut ueberschrieben sein koennen, es also schwer zu ueberblicken ist. "The weak attribute causes the declaration to be emitted as a weak symbol rather than a global." Hat das Einfluss auf den Scope?
Ich kann verstehen, dass "const" und "weak" für den Compilerbauer ein Alptraum sind. Aber das dürfte für die Kombination "extern const" doch auch schon zutreffen?
Walter Tarpan schrieb: > Aber das dürfte für die Kombination "extern const" doch > auch schon zutreffen? nur wenn er die Konstanten Variablen auch schon zur Compilezeit auswerten soll. C tut das nicht. Ansonsten ist es egal ob extern oder extern const, nur das halt kein Schreibzugriff erlaubt ist. Und auch const volatile stellt kein Problem dar, falls Du das meintest.
A. S. schrieb: > C tut das nicht. Stell doch bitte nicht pauschal solche Behauptungen auf.
1 | $ cat foo.c |
2 | extern const int i; |
3 | const int i = 42; |
4 | |
5 | int get_i(void) |
6 | { |
7 | return i; |
8 | } |
9 | $ cc -O -Wall -Wextra -S foo.c |
10 | $ cat foo.s |
11 | .file "foo.c" |
12 | .text |
13 | .globl get_i |
14 | .type get_i, @function |
15 | get_i: |
16 | .LFB0: |
17 | .cfi_startproc |
18 | movl $42, %eax |
19 | ret |
20 | .cfi_endproc |
21 | .LFE0: |
22 | .size get_i, .-get_i |
23 | .globl i |
24 | .section .rodata |
25 | .align 4 |
26 | .type i, @object |
27 | .size i, 4 |
28 | i: |
29 | .long 42 |
30 | .ident "GCC: (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0" |
31 | .section .note.GNU-stack,"",@progbits |
Jörg W. schrieb: > Stell doch bitte nicht pauschal solche Behauptungen auf. dass der Gnu C++ Compiler das soll und der Gnu-C das innerhalb einer Datei kann, geschenkt. Es bleibt dennoch eine in C nicht vorgesehene (und natürlich nicht verbotene) Optimierung. Wenn er das nicht tut, ist es OK. Wenn er das bei weak auch macht, ist es falsch. In einer normalen Lib (ohne weak) gibt es mit der Implementierung auch kein Problem, weil beide nur zusammen zugelinkt werden. Es ging darum, dass es zu keinem Problem bei verschiedenen Dateien führt, weil > C tut das nicht. Und wenn der Linker das mittlerweile in C trotzdem macht, … dann scheint es erst recht kein Problem für den Compiler-Bauer, weil er es ja nicht braucht. Es ging um diese Aussage: Walter Tarpan schrieb: > Ich kann verstehen, dass "const" und "weak" für den Compilerbauer ein > Alptraum sind. Aber das dürfte für die Kombination "extern const" doch > auch schon zutreffen? Und das ist halt falsch. const und weak machen nichts anderes, als mit einer Lib schon seit Ansi-C (oder früher) geht. Nur dass man ohne weak nicht innerhalb einer C-Datei Kirschenpflücken kann.
A. S. schrieb: > Jörg W. schrieb: >> Stell doch bitte nicht pauschal solche Behauptungen auf. > > dass der Gnu C++ Compiler das soll und der Gnu-C das innerhalb einer > Datei kann, geschenkt. Es bleibt dennoch eine in C nicht vorgesehene > (und natürlich nicht verbotene) Optimierung. Welche Optimierung ist denn deiner Meinung nach in C "vorgesehen"? Und in welcher Sprache ist das Optimieren von konstanten Ausdrücken im Compiler verpflichtend?
mh schrieb: > in welcher Sprache ist das Optimieren von konstanten Ausdrücken im > Compiler verpflichtend? C++ In C haben const-"Variablen" externe Bindung. Es muss auch funktionieren, wenn sie erst zur Laufzeit ausgelesen wird. In C++ ist sowas erlaubt wie const int n=11; int a[n];. In C geht das nicht (selbst wenn gcc das erlauben sollte).
A. S. schrieb: > mh schrieb: >> in welcher Sprache ist das Optimieren von konstanten Ausdrücken im >> Compiler verpflichtend? > > C++ > > In C haben const-"Variablen" externe Bindung. Es muss auch > funktionieren, wenn sie erst zur Laufzeit ausgelesen wird. > > In C++ ist sowas erlaubt wie const int n=11; int a[n];. In C geht das > nicht (selbst wenn gcc das erlauben sollte). Das ist keine Antwort auf meine Fragen. Mir ist der Unterschied zwischen C-const und C++-const bekannt.
A. S. schrieb: > dass der Gnu C++ Compiler das soll und der Gnu-C das innerhalb einer > Datei kann, geschenkt. Es bleibt dennoch eine in C nicht vorgesehene > (und natürlich nicht verbotene) Optimierung. Damit ist aber die pauschale Aussage, "wird in C nicht gemacht", Quatsch. Auf mehr wollte ich nicht hinaus: selbstverständlich darf auch ein C-Compiler ein const-Objekt als unveränderlich annehmen. > Wenn er das bei weak auch macht, ist es falsch. Kannst du so auch nicht sagen, denn "weak" ist nichts, was der Standard definiert. Die Dokumentation des Compilers macht dazu auch keine weitere Aussage (wurde ja oben schon zitiert). Letztlich interessiert den Compiler das überhaupt nicht (weder GCC noch Clang), wenn man in obigem Code ein "__attribute__((weak))" für die Variable einfügt. Der generierte Code bleibt der gleiche. Ergo: weak und const sollte man tunlichst nicht gemeinsam benutzen.
Maxe schrieb: > Naja, Optimierung ist ja nicht alles. Wenn die dafür sorgt, dass diese Idee gar nicht erst zuverlässig funktioniert, dann ist das erst mal ein k.o.-Kriterium. > Entscheidender scheint mir, dass die Konstanten irgendwo im Code verstreut > ueberschrieben sein koennen, es also schwer zu ueberblicken ist. Das sehe ich auch so. Wenn ich irgendwo im Quellcode eine Definition der const-Variablen mit Initialisierung sehe, dann erwarte ich eigentlich auch, dass sie diesen Wert hat und ihr nicht hinterrücks ein anderer Wert gegeben wird. A. S. schrieb: > Jörg W. schrieb: >> Stell doch bitte nicht pauschal solche Behauptungen auf. > > dass der Gnu C++ Compiler das soll und der Gnu-C das innerhalb einer > Datei kann, geschenkt. Mit LTO würde es mich nicht wundern, wenn er es auch über Quellcode-Dateien hinweg täte. > Es bleibt dennoch eine in C nicht vorgesehene (und natürlich nicht > verbotene) Optimierung. Wenn er das nicht tut, ist es OK. Und genauso ok ist es, wenn er das tut. > Wenn er das bei weak auch macht, ist es falsch. weak gibt es in C gar nicht. > Walter Tarpan schrieb: >> Ich kann verstehen, dass "const" und "weak" für den Compilerbauer ein >> Alptraum sind. Aber das dürfte für die Kombination "extern const" doch >> auch schon zutreffen? > > Und das ist halt falsch. const und weak machen nichts anderes, als mit > einer Lib schon seit Ansi-C (oder früher) geht. Libs sind in ANSI C auch nicht "vorgesehen". A. S. schrieb: > mh schrieb: >> in welcher Sprache ist das Optimieren von konstanten Ausdrücken im >> Compiler verpflichtend? > > C++ Nein. C++ verpflichtet nicht zu irgendwelchen Optimierungen. > In C haben const-"Variablen" externe Bindung. Es muss auch > funktionieren, wenn sie erst zur Laufzeit ausgelesen wird. Nur wenn sie auch volatile sind. Sonst darf der Compiler da beliebig dran rumoptimieren. > In C++ ist sowas erlaubt wie const int n=11; int a[n];. In C geht das > nicht (selbst wenn gcc das erlauben sollte). Und was hat das jetzt mit Optimierung zu tun?
Jörg W. schrieb: > Der Sinn darin, eine Variable als "const" zu deklarieren ist doch, dass > der Compiler (und nicht erst der Linker) darauf Optimierungen anwenden > kann, denn er muss nicht mehr davon ausgehen, dass sich deren Wert > jenseits der (für ihn sichtbaren) Initialisierung nochmal ändert. Nö. Eigentlich ist das eben nicht der Sinn des Ganzen, sondern der Sinn (und die Anwendung) ist, daß eben diese "Variable" nicht im RAM angeordnet sein soll, sondern im Flash. Manchmal braucht man genau das genau SO - und zwar derart, daß der Compiler daran nichts herum"optimiert". W.S.
W.S. schrieb: > Jörg W. schrieb: >> Der Sinn darin, eine Variable als "const" zu deklarieren ist doch, dass >> der Compiler (und nicht erst der Linker) darauf Optimierungen anwenden >> kann, denn er muss nicht mehr davon ausgehen, dass sich deren Wert >> jenseits der (für ihn sichtbaren) Initialisierung nochmal ändert. > > Nö. Eigentlich ist das eben nicht der Sinn des Ganzen, sondern der Sinn > (und die Anwendung) ist, daß eben diese "Variable" nicht im RAM > angeordnet sein soll, sondern im Flash. Das kann gar nicht die Aufgabe von const sein, aus einem einfachen Grund: C als Sprache weiß überhaupt nix von RAM oder Flash. Mit const sagt man dem Compiler lediglich, dass er annehmen darf, dass sich der Inhalt nie ändert. Das ist die einzige Aufgabe von const in C. Natürlich darf der Compiler bzw. Linker sich das zunutze machen, indem er die Variable dann in den Flash legt, sofern das geht. Das ist aber in gewissem Sinne auch eine Optimierung. > Manchmal braucht man genau das genau SO - und zwar derart, daß der > Compiler daran nichts herum"optimiert". Dann muss man dem Compiler eben ausdrücklich sagen, dass er das nicht tun soll. Genau dafür wäre volatile da.
:
Bearbeitet durch User
Rolf M. schrieb: > Nein. C++ verpflichtet nicht zu irgendwelchen Optimierungen. Das ist technisch korrekt. Aber man könnte "umgangssprachlich" sagen, dass es in C++ verpflichtende RVO gibt.
Rolf M. schrieb: > Mit const sagt man dem Compiler lediglich, dass er annehmen darf, dass > sich der Inhalt nie ändert. Nicht ganz: man sagt ihm, dass er keine Änderungsversuche darauf zulassen darf. Aber "const volatile" ist ganz legal, und auch als Erklärung dokumentiert als "maybe modified by hardware".
Was wäre denn für einen Compiler/Compilerbauer der Unterschied zwischen "const weak" und "const extern"? In beiden Fällen kann er die Werte erst beim Linken einsetzen.
:
Bearbeitet durch User
Walter T. schrieb: > Was wäre denn für einen Compiler/Compilerbauer der Unterschied zwischen > "const weak" und "const extern"? In beiden Fällen kann er die Werte erst > beim Linken einsetzen. Wenn die Variable zweimal definiert ist, einmal mit weak und einmal ohne, dann bekommt die ohne den Vorrang. Wenn keine von beiden weak ist, gibt es einen Fehler.
Walter T. schrieb: > Was wäre denn für einen Compiler/Compilerbauer der Unterschied zwischen > "const weak" und "const extern"? In beiden Fällen kann er die Werte erst > beim Linken einsetzen. Es geht nicht ums einsetzen, da C im Gegensatz zu C++ nicht einsetzt. Zumindest nicht braucht. Es geht darum, ob eine Definition durch eine zweite ersetzt werden darf. Mit einer lib ist das normal, aber in C immer für ein ganzes C-File, also alle Funktionen und variablen darin. Mit weak auch für einzelne
Wenn ein C File nur int a und b und Funktion f enthält, dann kann ich im Projekt alle drei entweder selber neu definieren oder keine. Mit weak a könnte ich stattdessen a neu definieren und b und f werden aus der lib genommen.
Walter T. schrieb: > as wäre denn für einen Compiler/Compilerbauer der Unterschied zwischen > "const weak" und "const extern"? In beiden Fällen kann er die Werte erst > beim Linken einsetzen. Die Frage bezieht sich auf die Aussage von Jörg Beitrag "Re: C: Konstante weak definieren"
Rolf M. schrieb: > Das kann gar nicht die Aufgabe von const sein, aus einem einfachen > Grund: C als Sprache weiß überhaupt nix von RAM oder Flash. Denke doch erstmal nach! Selbstverständlich weiß ein jeder Compiler (auch ein C-Compiler) zu unterscheiden zwischen Zeugs, was in den Code kommt und Zeugs, wofür lediglich Platz reserviert wird. Das gehört zu den elementaren Aufgaben eines Compilers! Begreife mal, daß sogenannte Hochsprachen (POS: problemorientierte Sprachen) eben genau zu dem Zweck erdacht worden sind, daß man sich als Programmierer nicht mit der Maschinenebene herumschlagen muß, wie das in Assembler vonnöten ist. Dein angeblicher Grund ist eine völlig unsinnige Annahme, denn es ist nicht die Programmiersprache, sondern der Compiler (kurz: die Toolchain), der von Ram und Rom und so weiter wissen muß. Letztendlich ist es egal, ob der Code in einen Flash im µC oder in ein schreibgeschütztes Code-Segment im PC kommt: Wichtig ist nur, daß klar ist, ob das eine Variable ist, für die man Platz im schreib- und lesbaren Speicher reservieren muß - oder ob das eine Konstante ist, die entsprechend ihres Typs ein oder mehrere Bytes groß ist und genau so wie die Bytes des Maschinencodes in das Codesegment/Flash hinein kommt. Und genau für diese Unterscheidung ist 'const' zuständig. Rolf M. schrieb: > Dann muss man dem Compiler eben ausdrücklich sagen, dass er das nicht > tun soll. Genau dafür wäre volatile da. Das ist schon das zweite totale Mißverständnis deinerseits! Nein, der Zweck von 'volatile' ist ein Workaround um den Fakt, daß C kein sauberes Modulkonzept kennt und deshalb nicht unterscheiden kann, ob ein Stück Code den exclusiven Zugriff auf eine Variable hat oder nicht. Deswegen ist es zum Steuern von eventuellen Optimierungen notwendig, Variablen, die sich durch andere Instanzen ändern können (Nachbar-Thread oder Hardware oder Interrupt oder mal bloß ein Zugriff per 'extern' von einer anderen Quelle aus) so zu kennzeichnen, daß der Compiler für diese keine lokale Kopie zwecks Optimierung erzeugt, sondern Lesezugriffe immer direkt codiert. Das hat überhaupt nichts mit der Anordnung der Variaben/Konstanten im Ram- oder Code-Segment zu tun. W.S.
W.S. schrieb: > Nein, der Zweck von 'volatile' ist ein Workaround um den Fakt, daß C > kein sauberes Modulkonzept kennt und deshalb nicht unterscheiden kann, > ob ein Stück Code den exclusiven Zugriff auf eine Variable hat oder > nicht. Absolut nicht. Bitte lies dir als erstes mal durch, was der Standard dazu sagt.
W.S. schrieb: > Rolf M. schrieb: >> Das kann gar nicht die Aufgabe von const sein, aus einem einfachen >> Grund: C als Sprache weiß überhaupt nix von RAM oder Flash. > > Denke doch erstmal nach! > > Selbstverständlich weiß ein jeder Compiler (auch ein C-Compiler) zu > unterscheiden zwischen Zeugs, was in den Code kommt und Zeugs, wofür > lediglich Platz reserviert wird. Ich hatte ganz bewusst von "C als Sprache" geschrieben, nicht vom Compiler. Schade, dass du das übersehen hast. Natürlich weiß der Compiler, wo er die Daten hinsteckt, aber das ist dessen Implementierungsdetail und nicht Bestandteil der Sprache selbst. const dagegen ist Bestandteil der Sprache. > Das gehört zu den elementaren Aufgaben eines Compilers! Ein Compiler für PC-Anwendungen kann in der Regel gar nichts in einen Flash stecken. Es wäre auch überhaupt nicht sinnvoll. Dennoch gibt es dort const, und es wird auch genutzt. Und es wurde auch schon bei Compilern für DOS benutzt, wo es auch keine Read-Only-Segmente gab. > Begreife mal, daß sogenannte Hochsprachen (POS: problemorientierte > Sprachen) eben genau zu dem Zweck erdacht worden sind, daß man sich als > Programmierer nicht mit der Maschinenebene herumschlagen muß, wie das in > Assembler vonnöten ist. Ja, eben. Deshalb definiert die Sprache von sich auch auch nicht so Dinge wie Flash und RAM. Darum kümmert sich der Compiler. > Dein angeblicher Grund ist eine völlig unsinnige Annahme, denn es ist nicht > die Programmiersprache, sondern der Compiler (kurz: die Toolchain), der von > Ram und Rom und so weiter wissen muß. Das bestätigt eher meine Aussage, denn das ist genau das, was ich geschrieben habe. Dagegen hast du beim Lesen meines Postings offenbar die Sprache mit dem Compiler verwechselt. > Rolf M. schrieb: >> Dann muss man dem Compiler eben ausdrücklich sagen, dass er das nicht >> tun soll. Genau dafür wäre volatile da. > > Das ist schon das zweite totale Mißverständnis deinerseits! > > Nein, der Zweck von 'volatile' ist ein Workaround um den Fakt, daß C > kein sauberes Modulkonzept kennt und deshalb nicht unterscheiden kann, > ob ein Stück Code den exclusiven Zugriff auf eine Variable hat oder > nicht. Das ist gelinde gesagt Blödsinn. Mit Modulen hat das überhaupt nichts zu tun. Volatile dient dazu, dass alle Zugriffe auf den Speicher auch wirklich ausgeführt werden, und das ist hier in diesem Fall erforderlich. > Deswegen ist es zum Steuern von eventuellen Optimierungen notwendig, > Variablen, die sich durch andere Instanzen ändern können (Nachbar-Thread > oder Hardware oder Interrupt oder mal bloß ein Zugriff per 'extern' von > einer anderen Quelle aus) so zu kennzeichnen, daß der Compiler für diese > keine lokale Kopie zwecks Optimierung erzeugt, sondern Lesezugriffe > immer direkt codiert. Das stimmt, abgesehen von "bloß ein Zugriff per 'extern'". Da ist ein volatile unnötig. Es ist nur dann erforderlich, wenn ein Zugriff außerhalb des normalen Programmflusses passiert, also wie du schon schreibst, durch einen Interrupt, durch externe Hardware oder durch einen anderen Thread. > Das hat überhaupt nichts mit der Anordnung der Variaben/Konstanten im Ram- > oder Code-Segment zu tun. Natürlich nicht. Das habe ich auch nicht behauptet. Es hat aber damit zu tun, dass hier der Wert der const-Variablen quasi nach dem Compilieren und beim Linken durch einen anderen ersetzt werden soll. Das funktioniert nur, wenn auch darauf zugegriffen wird und der Wert nicht z.B. einfach direkt im Code eingesetzt wird. Das kann man mit volatile sicherstellen.
:
Bearbeitet durch User
W.S. schrieb: > Eigentlich ist das eben nicht der Sinn des Ganzen, sondern der Sinn (und > die Anwendung) ist, daß eben diese "Variable" nicht im RAM angeordnet > sein soll, sondern im Flash. Dann wäre das Verwenden von "const" auf einem System ohne Flash (z.B. PC mit Windows oder Linux: nur RAM) also ein Fehler?!? Deine Erklärung ist einfach falsch. "const" sagt dem Compiler, dass der Wert dieser Variablen vom Programm nicht geändert werden darf. Quelle für Deine Behauptung?
W.S. schrieb: > Nö. Eigentlich ist das eben nicht der Sinn des Ganzen, sondern der Sinn > (und die Anwendung) ist, daß eben diese "Variable" nicht im RAM > angeordnet sein soll, sondern im Flash. Mal wieder keine Ahnung und zu engstirnig? Was ist denn mit Prozessoren welche erstmal ihr ganzes Programm per ROM Bootloader vom QSPI Flash in den DRAM kopieren und dann vollständig daraus laufen? Offensichtlich ist deine "Argumentation" mal wieder hahnebüchen und löchrig! Jörg hat da schon recht. Daher bitte ich darum: W.S. schrieb: > Denke doch erstmal nach!
Beitrag #6362452 wurde von einem Moderator gelöscht.
Rolf M. schrieb: > weak gibt es in C gar nicht guter Aspekt; kenne ich nämlich auch nicht ... aber vielleicht haben sie es ja im neuesten Standard dazu gekittert. Außerdem: https://en.wikipedia.org/wiki/Weak_symbol Weak symbols are not mentioned by the C or C++ language standards; as such, inserting them into code is not very portable. So gewöhnt man sich schlechten Programmierstil an ;-)
Rolf M. schrieb: > Das ist gelinde gesagt Blödsinn. Mit Modulen hat das überhaupt nichts zu > tun. Volatile dient dazu, dass alle Zugriffe auf den Speicher auch > wirklich ausgeführt werden, und das ist hier in diesem Fall > erforderlich. Das hat aber sehr wohl mit dem fehlenden Modulkonzept zu tun! Im Grunde könnte der Compiler für jeden Lesezugriff auf eine Variable eben auf diese zugreifen. Macht er aber aus Optimierungsgründen oftmals nicht. Jedoch kann ein C-Compiler bei globalen Variablen oder gar Hardware-Registern eben nicht feststellen, ob sich der Inhalt eben dieser Variable aus Gründen ändern kann, die außerhalb des Sichtbereiches der vorliegenden Quelle stehen. Hätte man in C ein Modulkonzept, was wie in Pascal ganz klar festlegt, was irgend eine andere Instanz überhaupt sehen kann und was nicht, dann bräuchte man sowas wie 'volatile' überhaupt nicht. Grund: der Compiler könnte selbst feststellen, ob in der Zwischenzeit, wo der gerade aktuelle Code läuft, von woanders ein Zugriff überhaupt möglich ist oder nicht. In C kann man im Prinzip jede irgendwo vorkommende Variable mit 'extern typ name' oder schlichtweg über das Einbinden der .h (sofern dort diese Variable erwähnt ist) erreichen. Damit ist der Compiler ausgehebelt, er kann nicht feststellen, ob die Variable von woanders her erreichbar ist oder nicht. Und genau DAS ist der eigentliche Punkt. Du hast bloß nicht gründlich genug nachgedacht. Und hier haben wir noch einen, der nicht nachgedacht hat: Frank M. schrieb: > Dann wäre das Verwenden von "const" auf einem System ohne Flash (z.B. PC > mit Windows oder Linux: nur RAM) also ein Fehler?!? Soviel Nicht-Denken-Wollen ärgert mich. Also für die Langsamdenker mal im Einzelnen: 1. const benötigt eine Wertfestlegung (const double a = 3.1415; ). Ist dir dieses klar? 2. und warum benötigt const eine Wertfestlegung? Ist dir der tiefere Grund dafür bewußt? Man könnte ja auch per #define a 3.1415 dem Augenschein nach dasselbe tun -aber der Augenschein trügt. 3. Der Grund ist, daß diese 3.1415 eben nicht in irgendwelche Maschinenbefehle eingebaut wird, sondern tatsächlich eine Variable ist, die jedoch im CODE steht. Im Mikrocontroller also im Flash, am PC je nach OS in einem schreibgeschützten (oder nicht schreibgeschützten) Stück RAM (wäre vom Prinzip her dasselbe wie Flash: R/O und nicht R/W). Das ist etwas anderes als das Vereinbaren einer Variablen, für die man ja nur Platz reservieren muß. Hast du das jetzt begriffen? > Deine Erklärung ist einfach falsch. "const" sagt dem Compiler, dass der > Wert dieser Variablen vom Programm nicht geändert werden darf. Siehe oben, du liegst falsch. Der Hauptgrund ist, daß diese Variable ein Teil des zu erzeugenden Codes wird und nicht, daß der Compiler weiß, daß man sie nicht beschreiben darf. Das ist ne Schlußfolgerung, die zwar logisch, am PC jedoch oftmal völlig falsch ist. Erinnere dich mal an die Zeiten von DOS: dort konnte man const vereinbaren und dennoch drauf herumschreiben. Ja, das ging. > Quelle für Deine Behauptung? Jede .exe Datei zum Beispiel. Also begreife mal: const ist dafür, daß etwas in den Code kommt - und zwar nicht implizit in den Maschinenbefehlen, sondern explizit als typisierte und mit Wert versehene Variable. volatile ist dafür, daß man dem Compiler ansagt, daß die Variable auch von anderen Instanzen geändert werden kann und der Compiler nicht die volle Kontrolle darüber hat - und das ist eine Spätfolge davon, daß in C einfach mit Header-Dateien gearbeitet wird, was so ziemlich das Gegenteil eines Modulkonzeptes ist und keinerlei Kapselung ermöglicht. Ist dir das nun klar? Ich habe nämlich den Eindruck, daß du nur stänkern wolltest. Jörg W. schrieb: > W.S. schrieb: >> Nein, der Zweck von 'volatile' ist ein Workaround um den Fakt, daß C >> kein sauberes Modulkonzept kennt und deshalb nicht unterscheiden kann, >> ob ein Stück Code den exclusiven Zugriff auf eine Variable hat oder >> nicht. > > Absolut nicht. Absolut doch. Hab das soeben noch einmal erklärt, siehe dieser Beitrag. Es gibt keinerlei sonstigen Grund für 'volatile'. Auch nicht in irgend einem Standard: der Grund für die Notwendigkeit von volatile in C ist nicht, daß es im Standard steht, sondern daß man dem Compiler etwas ansagen muß, was er aufgrund eines Mangels in der Sprachdefinition von selbst nicht wissen kann. So herum. So, Leute - im Grunde ärgert es mich nicht, daß ihr so tief mit der Nase in der C-Furche steckt, sondern es ist bedauerlich, daß ihr es nicht für nötig haltet, die Nase mal zu erheben und über den Rand der Furche zu schauen. W.S.
ohne Account schrieb: > Rolf M. schrieb: >> weak gibt es in C gar nicht > > guter Aspekt; kenne ich nämlich auch nicht ... aber vielleicht haben sie > es ja im neuesten Standard dazu gekittert. und: ohne Account schrieb: > Weak symbols are not mentioned by the C or C++ language standards; as > such, inserting them into code is not very portable. > > So gewöhnt man sich schlechten Programmierstil an ;-) Gröhl... Wer es nicht begreift, daß 'weak' eine zwingend einzuführende Sache ist, die ganz speziell für das Programmieren von Cortex-Architekturen erforderlich ist, der hat die letzten 10 Jahre geschlafen. Es ist eben kein schlechter Programmierstil, sondern eine Notwendigkeit, die allerdings auf Assembler-Ebene hätte bleiben können, wenn es nicht fanatische C-Anhänger gegeben hätte, die die Forderung aufgestellt hatten, daß sie selbst den Startup-Code ebenfalls in C formuliert haben wollen. Man hätte das abschlägig beantworten können und dann wäre weak niemals irgendwo in C aufgetaucht. Ist aber so nicht gelaufen. Selbstverständlich ist 'weak' überhaupt nicht als portable vorgesehen. Das ist ebenso plattformspeziell wie die Adressierung per CS:IP beim 8086. Warum weiß man hier - in einem dedizierten MIKROCONTOLLER Forum - so etwas nicht? W.S.
W.S. schrieb: > In C kann man im Prinzip jede irgendwo vorkommende Variable mit 'extern > typ name' oder schlichtweg über das Einbinden der .h (sofern dort diese > Variable erwähnt ist) erreichen. Das ist falsch. W.S. schrieb: > Hätte man in C ein Modulkonzept, was wie in Pascal ganz klar festlegt, > was irgend eine andere Instanz überhaupt sehen kann und was nicht, dann > bräuchte man sowas wie 'volatile' überhaupt nicht. Grund: der Compiler > könnte selbst feststellen, ob in der Zwischenzeit, wo der gerade > aktuelle Code läuft, von woanders ein Zugriff überhaupt möglich ist oder > nicht. Und mit diesem Modulkonzept weiß der Compiler dann, wann sich ein Hardwareregister ändert? Verkaufst du mir so ein Modul? Dann kann ich meine Kristallkugel entsorgen... Bist du dir sicher, dass du const in C verstanden hast? Wie genau erklärst du
1 | #include <stdlib.h> |
2 | int main() { |
3 | int const foo = rand(); |
4 | return foo; |
5 | }
|
Wird die Zufallszahl zur Laufzeit in den Flash/schreibgeschützten RAM geschrieben? W.S. schrieb: > Gröhl... Wer es nicht begreift, daß 'weak' eine zwingend einzuführende > Sache ist, die ganz speziell für das Programmieren von > Cortex-Architekturen erforderlich ist, der hat die letzten 10 Jahre > geschlafen. Kannst du etwas genauer erklären, warum man für Cortex unbedingt week braucht? Und warum man wegen dieser einen Architektur weak im C-Standard einführen muss?
W.S. schrieb: > Im Grunde könnte der Compiler für jeden Lesezugriff auf eine Variable > eben auf diese zugreifen. Macht er aber aus Optimierungsgründen oftmals > nicht. So weit noch richtig. > Jedoch kann ein C-Compiler bei globalen Variablen oder gar > Hardware-Registern eben nicht feststellen, ob sich der Inhalt eben > dieser Variable aus Gründen ändern kann, die außerhalb des > Sichtbereiches der vorliegenden Quelle stehen. Und das stimmt eben so nicht. Wie schon oben geschrieben, geht es nicht um alle Änderungen außerhalb des Sichtbereichs des Quellcodes, sondern um welche außerhalb des normalen Programmflusses. Also sobald Nebenhäufigkeiten durch Threads, Interrupts oder gleichzeitige Zugriffe durch externe Hardware vorkommen. Genau dann braucht man volatile, und genau dafür ist es auch gemacht. Ob dies nun innerhalb eines Moduls oder über mehrere Module hinweg passiert, ist dafür komplett unerheblich. > Hätte man in C ein Modulkonzept, was wie in Pascal ganz klar festlegt, > was irgend eine andere Instanz überhaupt sehen kann und was nicht, dann > bräuchte man sowas wie 'volatile' überhaupt nicht. Und wie sorgt dein Pascal-Modulkonzept dafür, dass der Compiler bei einer Schleife wie:
1 | while (true) |
2 | {
|
3 | if (interrupt_flag) |
4 | {
|
5 | led_pin = !led_pin; |
6 | interrupt_flag = false; |
7 | }
|
8 | }
|
weiß, dass interrupt_flag plötzlich irgendwann mitten drin durch eine ISR verändert werden kann? Und wie sorgt es dafür, dass für die Variable led_pin, die in diesem Fall ein Hardware-Register ist, auch auf jeden Fall immer ein vollständiger Schreibzugriff erfolgt, damit die LED auch tatsächlich toggelt? > In C kann man im Prinzip jede irgendwo vorkommende Variable mit 'extern > typ name' oder schlichtweg über das Einbinden der .h (sofern dort diese > Variable erwähnt ist) erreichen. Ja, aber das hat erst mal nichts, aber überhaupt nichts, mit volatile zu tun. > Damit ist der Compiler ausgehebelt, er kann nicht feststellen, ob die > Variable von woanders her erreichbar ist oder nicht. So lange ich (ohne Nebenläufigkeiten) keinen externen Code aufrufe, kann dieser auch nicht auf die Variable zugreifen, da er gar nicht zur Ausführung kommt. Deshalb braucht man dafür auch kein volatile. Mit Nebenläufigkeiten braucht man volatile, allerdings ist das nicht abhängig davon, ob der Code "woanders" steht oder nicht. Für das obige ISR-Flag ist volatile nötig, sowohl wenn der Code in der selben C-Datei steht, als auch, wenn er in einer anderen steht. Der Compiler weiß nämlich nicht, dass die ISR nicht wie eine normale Funktion aufgerufen werden muss, damit sie ausgeführt wird, sondern vielmehr durch externe Hardware getriggert den Programmfluss plötzlich mittendrin unterbricht, ohne dass dort je irgendwo ein Aufruf stehen würde. > 2. und warum benötigt const eine Wertfestlegung? Ist dir der tiefere > Grund dafür bewußt? Der ist doch ziemlich trivial. Wie soll da sonst je ein sinnvoller Wert rein kommen, wenn nicht bei der Initialisierung? Mit const sichere ich zu, dass ich später den Wert nicht mehr ändern werde. Es gibt also nur eine einzige Stelle, wo man sie mit einem Wert belegen kann. > 3. Der Grund ist, daß diese 3.1415 eben nicht in irgendwelche > Maschinenbefehle eingebaut wird, sondern tatsächlich eine Variable ist, > die jedoch im CODE steht. Nein. Wo die steht, ist immer noch Implementierungsdetail. C macht da keinerlei Vorgaben dazu. > Im Mikrocontroller also im Flash, am PC je nach OS in einem > schreibgeschützten (oder nicht schreibgeschützten) Stück RAM (wäre vom > Prinzip her dasselbe wie Flash: R/O und nicht R/W). Kann der Compiler so implementieren, muss er aber nicht. Und ist auch oft nicht. Das hat auch erst mal nichts damit zu tun, ob es um einen PC oder einen µC geht. Eine solche Unterscheidung kennt C gar nicht. Ein Gegenbeispiel gibt es auch: AVR. Eine extern-Variable, die einfach als const definiert ist, landet dort im RAM. > Das ist etwas anderes als das Vereinbaren einer Variablen, für die man > ja nur Platz reservieren muß. Hast du das jetzt begriffen? Es ist nichts anderes. >> Deine Erklärung ist einfach falsch. "const" sagt dem Compiler, dass der >> Wert dieser Variablen vom Programm nicht geändert werden darf. > > Siehe oben, du liegst falsch. Der Hauptgrund ist, daß diese Variable ein > Teil des zu erzeugenden Codes wird und nicht, daß der Compiler weiß, daß > man sie nicht beschreiben darf. Das ist ne Schlußfolgerung, die zwar > logisch, am PC jedoch oftmal völlig falsch ist. Es ist exakt umgekehrt. > Erinnere dich mal an die Zeiten von DOS: dort konnte man const vereinbaren > und dennoch drauf herumschreiben. Ja, das ging. Klar, wobei dabei nach C schon immer undefiniertes Verhalten rauskam. Und in der Praxis hat es auch nicht immer funktioniert, je nach Optimierungsverhalten des Compilers. Denn er darf ja auf Grund meiner Zusicherung "const" annehmen, dass sich der Inhalt niemals ändert und das entsprechend bei seinen Optimierungen berücksichtigen. > Also begreife mal: > const ist dafür, daß etwas in den Code kommt - und zwar nicht implizit > in den Maschinenbefehlen, sondern explizit als typisierte und mit Wert > versehene Variable. Kann beides sein, kann auch was anderes sein. Das bleibt komplett dem Compiler überlassen, und es gibt in der Praxis alle Varianten. Wie du das als Beleg für deine dem entgegenstehende Theorie sehen kannst, erschließt sich mir beim besten Willen nicht. > volatile ist dafür, daß man dem Compiler ansagt, daß die Variable auch > von anderen Instanzen geändert werden kann Der wichtige Teil, der hier wieder fehlt: gleichzeitig! Wenn ich eine Funktion ganz einfach aufrufe, sie eine Variable verändert und dann wieder zurückkehrt, ist volatile selbstverständlich vollkommen überflüssig, egal ob diese Funktion oder die Variable in der selben oder einer anderen C-Datei definiert ist. > Hab das soeben noch einmal erklärt, siehe dieser Beitrag. Es gibt > keinerlei sonstigen Grund für 'volatile'. Oh mann… es gibt ausschließlich "sonstige Gründe", weil der von dir angebrachte Grund einfach Unsinn ist. > Auch nicht in irgend einem Standard: der Grund für die Notwendigkeit von > volatile in C ist nicht, daß es im Standard steht, sondern daß man dem > Compiler etwas ansagen muß, was er aufgrund eines Mangels in der > Sprachdefinition von selbst nicht wissen kann. So herum. Auch nicht. Das volatile ist gerade das, was dafür sorgt, dass es diesen Mangel in der Sprachdefinition nicht gibt. > So, Leute - im Grunde ärgert es mich nicht, daß ihr so tief mit der Nase > in der C-Furche steckt, sondern es ist bedauerlich, daß ihr es nicht für > nötig haltet, die Nase mal zu erheben und über den Rand der Furche zu > schauen. Mich ärgert es allerdings, dass du so daneben liegst und da so hartnäckig daran festhältst, ohne mal darüber zu reflektieren, ob es nicht vielleicht doch eben du bist, der hier falsch liegt.
W.S. schrieb: > Frank M. schrieb: >> Deine Erklärung ist einfach falsch. "const" sagt dem Compiler, dass der >> Wert dieser Variablen vom Programm nicht geändert werden darf. > > Siehe oben, du liegst falsch. Tut mir leid, ich habe an dieser Stelle keine Lust mehr, mit jemandem zu diskutieren, der überhaupt keine Ahnung hat, dies aber vehement vorgibt. Ich bleibe bei meiner Aussage. Lerne erstmal C, bevor Du weiter mit solchen Behauptungen kommst. Wenn Du es tatsächlich geschafft hast, unter DOS in C eine const-Variable tatsächlich zu ändern, war der verwendete Compiler schlichtweg fehlerhaft. Das Schlüsselwort "const" gibt es für C seit 1984 (C++: 1983).
Rolf M. schrieb: >> volatile ist dafür, daß man dem Compiler ansagt, daß die Variable auch >> von anderen Instanzen geändert werden kann > > Der wichtige Teil, der hier wieder fehlt: gleichzeitig! Gleichzeitig ist da wohl der falsche Begriff. volatile sagt dem Compiler, daß sich die Variable JEDERZEIT durch Vorgänge, die völlig ausserhalb seines Vorstellungsvermögens (sprich : Ausserhalb des Scopes der Sprachdefinition) liegen, ändern kann. Oliver
W.S. schrieb: > Nö. Eigentlich ist das eben nicht der Sinn des Ganzen, sondern der Sinn > (und die Anwendung) ist, daß eben diese "Variable" nicht im RAM > angeordnet sein soll, sondern im Flash. Zitat aus dem Standard (hier C++17 draft, aber egal):
1 | 134)The implementation may place a const object that is not volatile in a read-only region of storage. Moreover, the |
2 | implementation need not allocate storage for such an object if its address is never used. |
Die Anordnung im "Flash" ist unverbindlich und implementationsabhängig, und eine Existenz im Speicher überhaupt ist explizit nur dann gefordert, wenn es unvermeidlich ist. Das kann daher gar nicht der Sinn des Ganzen sein. Oliver
:
Bearbeitet durch User
Bitte nicht den ganzen Thread nochmal aufrollen. Letztlich wurde W.S. da oben inhaltlich schon (mehrfach) widerlegt.
:
Bearbeitet durch Moderator
Frank M. schrieb: > Tut mir leid, ich habe an dieser Stelle keine Lust mehr, mit jemandem zu > diskutieren, der überhaupt keine Ahnung hat, dies aber vehement vorgibt. > Ich bleibe bei meiner Aussage. Das ist dein Problem. Und ich bleibe bei meiner Aussage: const ist dafür da, eine KONSTANTE und zwar eine typisierte Konstante zu erzeugen. Alles andere ist nebensächlich, einschließlich Jörgs Herumhacken auf irgendwelchen Standards. manchmal kommt mir Jörg vor wie Herr Palmström: https://www.oppisworld.de/morgen/palm09.html Anstatt den digitalen Tatsachen ins Auge zu sehen, blickt er lieber in den Standard - und was da nicht steht, das gibt es auch nicht. Uff. So, jetzt weißt du wieder nicht, was eine typisierte Konstante ist. Ich hab das ja weiter oben schon gesehen, hielt deinen dummen Spruch jedoch für einen Scherz. Nun sehe ich, daß du das ernst meinst. Also schaue dir mal das an:
1 | in Pascal: |
2 | var
|
3 | SimplePi = 3.1415; |
4 | TypisisertPi : double = 3.1415; |
5 | |
6 | oder in C: |
7 | #define SimplePi 3.1415
|
8 | const double TypisisertPi = 3.1415; |
Erkennst du an diesem Beispiel den gravierenden Unterschied zwischen SimplePi und TypisiertPi ? SimplePi wird bei Bedarf lediglich in irgendwelchen Maschinenbefehlen verwendet, aber TypisiertPi erzeugt Code, also etwas, das nicht nur Platz belegt, sondern auch mit einem Inhalt daherkommt und folglich beim PC in die .EXE und damit auf die Disk kommt und am µC eben in den Flash (wie ich bereits sagte). Und letzteres gilt auch dann, wenn TypisiertPi beim Programmstart in den RAM kopiert wird. Aus der Luft kommt es ja nicht, also muß es im gespeicherten Code vorhanden sein. Kapierst du das Ganze jetzt endlich? W.S.
W.S. schrieb: > einschließlich Jörgs Herumhacken auf irgendwelchen Standards Definierst du dir eigentlich auch deine eigenen Schrauben, oder hälst du dich dort doch lieber an Standards? Kann ja sein, dass du dir deine eigene Programmiersprache definierst, aber es wäre dann fair gegenüber den anderen Forennutzern, wenn du dieser zumindest einen anderen Namen geben würdest, "WS" vielleicht - damit die anderen das nicht mit einer einigermaßen populären und standardisierten Sprache verwechseln, was du da so definierst. Sorry, mehr kann man dazu leider nicht sagen. Vernünftige Begriffe, auf die sich alle anderen geeinigt haben, willst du ja schließlich nicht verwenden.
W.S. schrieb: > SimplePi wird bei Bedarf lediglich in irgendwelchen Maschinenbefehlen > verwendet, aber TypisiertPi erzeugt Code, also etwas, das nicht nur > Platz belegt, sondern auch mit einem Inhalt daherkommt und folglich > beim PC in die .EXE und damit auf die Disk kommt und am µC eben in den > Flash (wie ich bereits sagte). Kannst du kein Englisch, oder warum verstehst du den, von Oliver S. zietierten, Ausschnitt aus dem Standard nicht? Oder verstehe ich nicht was du mit "erzeugt Code" und "belegt Platz" ausdrücken willst?
:
Wiederhergestellt durch Moderator
Walter T. schrieb: > Ich will in einer .c-Datei ein "Default" einer > (struct)-Konfigurationsvariablen anlegen, die aber in einer anderen > Datei überschreiben können. Das ist nur sinnvoll, wenn is unterschiedliche Generieungsvarianten gibt, und die werden üblicherweise über die Generierungsumgebung verwaltet, z.B. über ein Makefile. Und genau dort kannst du unterschiedliche Generierungsvarianten vor Belegung "A" oder "B" festlegen. Resultat wären etwa: * Unterschiedliche Präprozessor-Defines je nach Variante, also gcc -D... * Unterschiedliche Module mit der Vorbelegung wie module-A.c und module-B.c, wobei nur genau eines der Module wirklich gelinkt wird.
W.S. schrieb: > Und ich bleibe bei meiner Aussage: const ist dafür da, eine KONSTANTE > und zwar eine typisierte Konstante zu erzeugen. Alles andere ist > nebensächlich Das ist auf Quelltextebene richtig, mit allen Vorteilen einer typischeren Programmierung gegenüber einer define-Konstanten. Im kompilierten Programmcode landet die const-Variable aber nur, wenn der Compiler die nicht wegoptimieren kann. Meistens kann und tut er das aber. Oliver
:
Bearbeitet durch User
W.S. schrieb: > Kapierst du das Ganze jetzt endlich? Du hast mal wieder nix kapiert! Der Verleich mit dem precompiler und einer const ist ja echt mal wieder hanebüchen. Sowas kann nur von dir kommen. Nur mal so als tip: ARM z.B. legt lokales direkt hinter den Codeblock. Das wäre jetzt dein "erzeugt Code" und "belegt Platz". Das const double kommt übrigens nicht ind en Flash bei ARM, der Compiler is mal wieder schlauer als du ;)
1 | void ws_kann_mal_wieder_nix(void) { |
2 | printf("thats pi: %f", SimplePi); |
3 | }
|
SimplePi ist einmal const und einmal das define. Dann jeweils mal copiled und: Bei beiden kommt übrigens raus:
1 | 08000cfc <_Z22ws_kann_mal_wieder_nixv>: |
2 | 8000cfc: b510 push {r4, lr} |
3 | 8000cfe: 4a03 ldr r2, [pc, #12] ; (8000d0c <_Z22ws_kann_mal_wieder_nixv+0x10>) |
4 | 8000d00: 4b03 ldr r3, [pc, #12] ; (8000d10 <_Z22ws_kann_mal_wieder_nixv+0x14>) |
5 | 8000d02: 4804 ldr r0, [pc, #16] ; (8000d14 <_Z22ws_kann_mal_wieder_nixv+0x18>) |
6 | 8000d04: f003 fa24 bl 8004150 <iprintf> |
7 | 8000d08: bd10 pop {r4, pc} |
8 | 8000d0a: 46c0 nop ; (mov r8, r8) |
9 | 8000d0c: c083126f addgt r1, r3, pc, ror #4 |
10 | 8000d10: 400921ca andmi r2, r9, sl, asr #3 |
11 | 8000d14: 08005148 stmdaeq r0, {r3, r6, r8, ip, lr} |
Die "komisch" disassemblierten Befehle ab 8000d0c sind übrigens die lokalen Konstanten ;) DU solltest eben einfach mal leise sein wenn sich die Erwachsenen unterhalten!
Mw E. schrieb: > DU solltest eben einfach mal leise sein wenn sich die Erwachsenen > unterhalten! Bitte nicht auf diesem Niveau. W.S. ist streitbar (und natürlich sind alle anderen die Geisterfahrer, nur er nicht), aber diese Tonart brauchen wir nicht im Forum.
Jörg W. schrieb: > Mw E. schrieb: >> DU solltest eben einfach mal leise sein wenn sich die Erwachsenen >> unterhalten! > > Bitte nicht auf diesem Niveau. Das ist halt das Niveau von W.S., an das sich die anderen hier anpassen: W.S. schrieb: > Soviel Nicht-Denken-Wollen ärgert mich. > > Also für die Langsamdenker mal im Einzelnen: W.S. schrieb: > Gröhl... Wer es nicht begreift, W.S. schrieb: > hielt deinen dummen Spruch jedoch für einen Scherz
Rolf M. schrieb: > Das ist halt das Niveau von W.S., an das sich die anderen hier anpassen: Stimmt auch wieder. Da in diesem Thread sowieso alles gesagt worden ist, was zum Thema gehört, würde ich Rolfs Worte einfach mal als Abschlussworte so stehen lassen.