Hallo, warum funktioniert folgender code nicht?
1 | static const char testConst =18; |
2 | static struct { |
3 | char test1; |
4 | char test2; |
5 | } testSC = |
6 | {
|
7 | .test1=42, // < OK |
8 | .test2=testConst // Error[Pe028]: expression must have a constant value |
9 | };
|
|
|
Forum: Mikrocontroller und Digitale Elektronik c constVar bei init von struct benutzenHallo, warum funktioniert folgender code nicht?
... das ist IAR. @TO: Welche Version hast Du am Start? VG, Stephan IAR 8.50.4, allerdings meckert der Clang von VS Code das auch an Das ist in C grundsätzlich nicht möglich, weil es da keine echten Konstanten gibt. "const" bedeutet nur, dass man sie nicht selbst ändern darf. So etwas geht in C nur mit enum oder Makros. In C++ geht es hingegen schon, nur da gibt es die designated initializers nicht... Eine Variable (in c) ist nun mal keine constant expression, ob da nun const davor steht oder nicht, ist egal. In C++ gibt es constexpr für sowas (wobei dort auch const etwas anders gehandhabt wird und geht), in C leider noch nicht. Da muss man noch auf enums oder macros zurück greifen, oder bei dem Anwendungsfall oben, die Variable in einer Funktion initialisieren. Viele Compiler haben da auch die __attribute__((constructor)) extension, die bei sowas nützlich werden kann. g4st schrieb: > Vermutlich musst du im Compiler C99 aktivieren. Das ist von der C-Version unabhängig. Programmierer schrieb: > In C++ geht es hingegen schon, nur da gibt es die designated > initializers nicht... Inzwischen gibt's die dort auch, sind aber noch ziemlich neu: https://en.cppreference.com/w/cpp/language/aggregate_initialization Ärgerlicherweise muss man aber zwingend die Reihenfolge aus der Typdefinition einhalten, wodurch das Feature wesentlich weniger nützlich als in C ist. Rolf M. schrieb: > Das ist von der C-Version unabhängig. Ja, aber mit C99 ("designated initializers") und den - compilerabhängigen - Erweiterungen zum ISO Standard funktioniert es dann dennoch. Vorausgesetzt natürlich man hat im Compiler keine "strict"-Option o. ä. aktiv und der Compiler unterstützt die entsprechende Erweiterung. g4st schrieb: > Rolf M. schrieb: >> Das ist von der C-Version unabhängig. > > Ja, aber mit C99 ("designated initializers") und den - > compilerabhängigen - Erweiterungen zum ISO Standard funktioniert es dann > dennoch. Ok, die designated initializers gibt's erst ab C99. > Vorausgesetzt natürlich man hat im Compiler keine "strict"-Option o. ä. aktiv > und der Compiler unterstützt die entsprechende Erweiterung. Hmm, gcc 9.3 und clang 10 lassen das zu und geben im C99-Modus selbst mit -pedantic nicht mal eine Warnung aus. Eigentlich bin ich mir aber ziemlich sicher, dass das in C so nicht erlaubt ist. Damit wäre das ein Compiler-Bug. Auch interessant: Wenn man den Initialisierungswert weglässt und damit die Variable implizit mit 0 initialisiert wird, bricht der Compiler mit Fehler ab, weil es ja keine Compilezeit-Konstante ist. ok, ein const ist nicht Konstant, sondern hat nur einen konstanten (nicht änderbaren) Wert, von dem der Compiler aber nicht ausgeht das er Konstant ist. Habe es jetzt ganz oldschool mit #define gemacht. zwei fragen zu den Antworten noch 1) was würde mir in dem Zusammenhang "__attribute__((constructor))" bringen? So wie ich es verstehe, kann dieses ja nur einmal im Programm verwendet werden. Da ich aber ein Modul schreibe, und nicht wissen kann ob es nicht ggf. im Hauptprogramm schon verwendet wird, scheidet es für mich aus. Weiterhin wo ist der Vorteil gegenüber einem Aufruf einer init Funtion vor der main-while Schleife? 2) in welchen Fällen wird idealerweise #define, enum, const verwendet? mrXYZ schrieb: > 1) > was würde mir in dem Zusammenhang "__attribute__((constructor))" > bringen? > So wie ich es verstehe, kann dieses ja nur einmal im Programm verwendet > werden. Wie kommst du darauf? > Weiterhin wo ist der Vorteil gegenüber einem Aufruf einer init Funtion > vor der main-while Schleife? Dass du keine init-Funktion in main() aufrufen musst :) > 2) > in welchen Fällen wird idealerweise #define, enum, const verwendet? Da gibt's unterschiedliche Ansichten dazu. In C verwende ich für Konstanten immer #define. enum verwende ich - wie der Name schon sagt - für Aufzählungstypen, aber nicht, um Einzelkonstanten zu definieren. const verwende ich eigentlich nur bei lokalen Variablen, primär um damit zu dokumentieren (und sicherzustellen), dass ich den Wert nicht ändern will. globale const-Variablen halte ich in C für wenig nutzbringend. wow, das geht ja wirklich mit dem __attribute__((constructor)) in mehrerern dateien, habe es gerade getestet :) ich hatte es vorher mit dem IAR __low_level_init() probiert, wobei dieses nur einmal verwendet werden kann wieder was gelernt, wobei ich erst einmal weiterhin ohne init Funktion arbeiten werde. 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.
|
|