Forum: Compiler & IDEs Variable nicht initialisiert


von Peter Z. (Gast)


Lesenswert?

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...

von Peter II (Gast)


Lesenswert?


von Markus F. (mfro)


Lesenswert?

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).

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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
von Dennis Restle (Gast)


Lesenswert?

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.

von Kaj (Gast)


Lesenswert?

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.

von Hans (Gast)


Lesenswert?

Wenn sie nicht initialisiert werden müssen, sollte es auch keine Warnung 
geben. Zeig doch mal ein Beispiel.

von Markus F. (mfro)


Lesenswert?

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.

von GCC (Gast)


Lesenswert?

Die Warnungen einfach ignorieren wäre zu einfach?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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.

von Blubb (Gast)


Lesenswert?

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.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Blubb schrieb:
> -mtiny-stack

Das da ist keine gute Idee!

von Blubb (Gast)


Lesenswert?

Wie gesagt, TESTEN...
Ich habe Projekte, da ist das unproblematisch.

von Simon K. (simon) Benutzerseite


Lesenswert?

... Bis man irgendwann was ändert, nichts mehr läuft und man nicht weiß 
warum

von Blubb (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.