Ich habe in meinem Code ein paar uint64_t Variablen, die nicht initialisiert werden müssen. Andere Variablen hingegen müssen sehr wohl initialisiert werden. Wie kann ich dem Compiler sagen: "schau her, bei diesen bitte keine Warnung, wenn ich sie nicht initialisiere" Hintergrund ist meine µC ist zu klein, "Programm Memory usage 99,2%" Ich kämpfe um jedes Byte, Code ist fast fertig, sitze nur an letzten Bugs und kannn µC nicht mehr auslöten da Platine schon mit einem mittel-riesigen Kühlkörper verklebt. Und ich weiss das es dämlich ist, Variablen nicht zu initialisieren...
Aus dem gcc-Manual:
1 | #pragma GCC diagnostic push
|
2 | #pragma GCC diagnostic ignored "-Wuninitialized"
|
3 | foo(b); /* no diagnostic for this one */ |
4 | #pragma GCC diagnostic pop
|
Geht aber nur bei neueren gcc-Versionen (ausprobieren).
Peter II schrieb: > The .noinit Section Die hilft hier sehr wahrscheinlich nicht: globale Variablen sind ja immer initialisiert, insofern wirft der Compiler dafür keine Warnungen (und nur darum geht's dem anderen Peter ja). Peter Zz schrieb: > "schau her, bei diesen bitte keine Warnung, wenn ich sie nicht > initialisiere" Sowas hier geht, aber nur für ganze Funktionen (denn auf Ebene der Funktionen prüft der Compiler):
1 | #include <stdint.h> |
2 | |
3 | #pragma GCC diagnostic push
|
4 | #pragma GCC diagnostic ignored "-Wuninitialized"
|
5 | int
|
6 | main(void) |
7 | {
|
8 | uint64_t dummy; |
9 | |
10 | return dummy; |
11 | }
|
12 | #pragma GCC diagnostic pop
|
Edit: Markus war ein bisschen schneller. ;-)
:
Bearbeitet durch Moderator
Es gibt Compiler die nehmen mit 0 Initialisierte Variablen und schreiben diese in die BSS Section. Beim Programmstart wird der Bereich dann mit 0 gefüllt. Damit sind alle Variablen initialisiert ohne Platz im Programmspeicher zu fressen (bis auf die Initialisierungsroutine). Bei einem Größere Projekt gibt es auch die Variante die Initialisierten Speiucherbereiche zu Komprimieren und beim Start mit einer Initialisierungsroutine wieder zu entpacken.
Peter Zz schrieb: > Ich habe in meinem Code ein paar uint64_t Variablen, die nicht > initialisiert werden müssen. Andere Variablen hingegen müssen sehr wohl > initialisiert werden. Wie kann ich dem Compiler sagen: > "schau her, bei diesen bitte keine Warnung, wenn ich sie nicht > initialisiere" Mach die Variablen global, dann werden die mit 0 initialisiert, sofern du nichts anderes angiebts. Brauchst du denn wirklich uint64? uint32 statt uint64 spart auch schon wieder viel programmspeicher beim initialisieren. Atmel Studio 6.2 (projekt fur AVR), GCC 4.8.1, optimierung ist abgeschaltet Lokal ohne Initialisierung:
1 | #include <stdint.h> |
2 | |
3 | int main(void) |
4 | {
|
5 | uint64_t a0; |
6 | uint64_t a1; |
7 | uint64_t a2; |
8 | uint64_t a3; |
9 | uint64_t a4; |
10 | uint64_t a5; |
11 | uint64_t a6; |
12 | uint64_t a7; |
13 | uint64_t a8; |
14 | uint64_t a9; |
15 | uint64_t a10; |
16 | uint64_t a11; |
17 | |
18 | while(1); |
19 | }
|
1 | Program Memory Usage : 264 bytes |
Globale Initialisierung mit 0:
1 | #include <stdint.h> |
2 | |
3 | uint64_t a0; |
4 | uint64_t a1; |
5 | uint64_t a2; |
6 | uint64_t a3; |
7 | uint64_t a4; |
8 | uint64_t a5; |
9 | uint64_t a6; |
10 | uint64_t a7; |
11 | uint64_t a8; |
12 | uint64_t a9; |
13 | uint64_t a10; |
14 | uint64_t a11; |
15 | |
16 | int main(void) |
17 | {
|
18 | while(1); |
19 | }
|
1 | Program Memory Usage : 280 bytes |
Globale Initialisierung:
1 | #include <stdint.h> |
2 | |
3 | uint64_t a0 = 0; |
4 | uint64_t a1 = 123; |
5 | uint64_t a2 = 43534645; |
6 | uint64_t a3 = 45645; |
7 | uint64_t a4 = 6758; |
8 | uint64_t a5 = 678; |
9 | uint64_t a6 = 456; |
10 | uint64_t a7 = 33; |
11 | uint64_t a8 = 34555346; |
12 | uint64_t a9 = 56756734563; |
13 | uint64_t a10 = 356457; |
14 | uint64_t a11 = 58790087; |
15 | |
16 | int main(void) |
17 | {
|
18 | while(1); |
19 | }
|
1 | Program Memory Usage : 306 bytes |
Lokale Initialisierung:
1 | #include <stdint.h> |
2 | |
3 | int main(void) |
4 | {
|
5 | uint64_t a0 = 0; |
6 | uint64_t a1 = 123; |
7 | uint64_t a2 = 43534645; |
8 | uint64_t a3 = 45645; |
9 | uint64_t a4 = 6758; |
10 | uint64_t a5 = 678; |
11 | uint64_t a6 = 456; |
12 | uint64_t a7 = 33; |
13 | uint64_t a8 = 34555346; |
14 | uint64_t a9 = 56756734563; |
15 | uint64_t a10 = 356457; |
16 | uint64_t a11 = 58790087; |
17 | |
18 | while(1); |
19 | }
|
1 | Program Memory Usage : 626 bytes |
Wie du siehst, braucht die globale initialisierung nur die hälfte an speicher. Ist meiner Meinung nach die schönste Methode, da man variablen nur dann global machen sollte, wenn man sie auch global braucht (z.B. in einer isr), aber das ist ja jedem selbst überlassen ;) Peter Zz schrieb: > "schau her, bei diesen bitte keine Warnung, wenn ich sie nicht > initialisiere" Warnungen "abschalten" halte ich für den "falschen" weg, da Warnungen ja einen Grund haben. Ob du die Warnungen nun für gesonderte Bereiche abschaltest bzw. versteckst, oder einfach ignorierst, kommt dabei auf's gleiche raus. Dann würde ich persönlich das ignorieren der Warnungen aber vorziehen.
Wenn sie nicht initialisiert werden müssen, sollte es auch keine Warnung geben. Zeig doch mal ein Beispiel.
Hans schrieb: > Wenn sie nicht initialisiert werden müssen, sollte es auch keine Warnung > geben. Zeig doch mal ein Beispiel. Es gibt tatsächlich einige Fälle, bei denen gcc nicht erkennt (erkennen kann), daß Variablen tatsächlich nur initialisiert verwendet werden (in switch()-Anweisungen, beispielsweise). Davon kann man aber etliche auch programmtechnisch "entschärfen". Für den Rest bleibt dann eben das selektive Abschalten.
GCC schrieb: > Die Warnungen einfach ignorieren wäre zu einfach? Das kann ziemlich nervig sein wenn in den Warnungen andere, wichtige Warnungen untergehen. Es ist dann ätzend die relevanten Warnungen rauszufischen.
Versuche mal ein paar Optimierungsparameter -finline-limit=0 -fipa-pta -fkeep-inline-functions -fno-caller-saves -fno-inline-small-functions -fno-tree-scev-cprop -ftree-loop-if-convert-stores -fweb -maccumulate-args -mcall-prologues -morder2 -mstrict-X -mtiny-stack Einzeln(!) testen, dann ggf. kombinieren.
Wie gesagt, TESTEN... Ich habe Projekte, da ist das unproblematisch.
... Bis man irgendwann was ändert, nichts mehr läuft und man nicht weiß warum
Nunja, bei großen Projekten ist oft der RAM so voll, dass ohnehin kein Platz für einen großen Stack ist. Klar kann es irgendwann knallen, aus den unterschiedlichsten Gründen, aber der Compiler ist ja auch nicht dein Kindermädchen.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.