PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C-Compiler, Warning fehlt ?



Siro
20.07.2011, 15:11
Hallo,
ich hab grad ein C-Problemchen gelöst und wundere mich das Verhalten des Compilers:

Ich habe vergessen eine lokale Variable zu initialisieren bevor ich sie abfrage (jaja, ich schäme mich ja auch dafür)
Aber hätte der Compiler das nicht gleich mit einem "Warning" tadeln müssen ?


void testfunc(void)
{ int time;

while (1)
{
if (time > 1) ;
}
}

Das ist jetzt sicherlich kein Sinnvoller code, daß soll nur das Problem aufdecken.
Ich habe den Code immer weiter gekürzt, bis dies übrig blieb.

Wenn ich jedoch folgendes schreibe, merkt der Compiler sofort, daß ich vergessen habe "time" zu initialisieren
und warnt korrekterweise mit folgender Meldung: variable "time" is used before its value is set.


void testfunc(void)
{ int time;

while (1)
if (time > 1) ;

}

Wo ist denn da der Unterschied ? oder was habe ich noch nicht richtig verstanden ?
Warum gibt es also in oberen Version keinen Warning ? während dessen in der unteren Version schon ?

Danke vorab für Eure Hilfe
Siro

radbruch
20.07.2011, 15:42
Hallo

Ich erhalte überhaupt keine Warnungen:
void testfunc(void)
{ int time;

while (1)
{
if (time > 1) ;
}
}

void testfunc2(void)
{ int time;

while (1)
if (time > 1) ;

}

int main(void)
{
testfunc();
testfunc2();
while(1);
return(0);
}Beide Varianten werden auch identisch übersetzt:
1 .file "test.c"
2 __SREG__ = 0x3f
3 __SP_H__ = 0x3e
4 __SP_L__ = 0x3d
5 __CCP__ = 0x34
6 __tmp_reg__ = 0
7 __zero_reg__ = 1
15 .Ltext0:
16 .global testfunc
18 testfunc:
19 .LFB2:
20 .LM1:
21 0000 DF93 push r29
22 0002 CF93 push r28
23 0004 00D0 rcall .
24 0006 CDB7 in r28,__SP_L__
25 0008 DEB7 in r29,__SP_H__
26 /* prologue: function */
27 /* frame size = 2 */
28 .L2:
29 000a 00C0 rjmp .L2
30 .LFE2:
32 .global testfunc2
34 testfunc2:
35 .LFB3:
36 .LM2:
37 .LM3:
38 000c DF93 push r29
39 000e CF93 push r28
40 0010 00D0 rcall .
41 0012 CDB7 in r28,__SP_L__
42 0014 DEB7 in r29,__SP_H__
43 /* prologue: function */
44 /* frame size = 2 */
45 .L5:
46 0016 00C0 rjmp .L5
47 .LFE3:
49 .global main
51 main:
52 .LFB4:
53 .LM4:
54 .LM5:
55 0018 DF93 push r29
56 001a CF93 push r28
57 001c CDB7 in r28,__SP_L__
58 001e DEB7 in r29,__SP_H__
59 /* prologue: function */
60 /* frame size = 0 */
61 .LM6:
62 0020 00D0 rcall testfunc
63 .LM7:
64 0022 00D0 rcall testfunc2
65 .L8:
66 0024 00C0 rjmp .L8
67 .LFE4:
109 .Letext0:
DEFINED SYMBOLS
*ABS*:00000000 test.c
C:\Users\mic\AppData\Local\Temp/cciawUNb.s:2 *ABS*:0000003f __SREG__
C:\Users\mic\AppData\Local\Temp/cciawUNb.s:3 *ABS*:0000003e __SP_H__
C:\Users\mic\AppData\Local\Temp/cciawUNb.s:4 *ABS*:0000003d __SP_L__
C:\Users\mic\AppData\Local\Temp/cciawUNb.s:5 *ABS*:00000034 __CCP__
C:\Users\mic\AppData\Local\Temp/cciawUNb.s:6 *ABS*:00000000 __tmp_reg__
C:\Users\mic\AppData\Local\Temp/cciawUNb.s:7 *ABS*:00000001 __zero_reg__
C:\Users\mic\AppData\Local\Temp/cciawUNb.s:18 .text:00000000 testfunc
C:\Users\mic\AppData\Local\Temp/cciawUNb.s:34 .text:0000000c testfunc2
C:\Users\mic\AppData\Local\Temp/cciawUNb.s:51 .text:00000018 main

NO UNDEFINED SYMBOLSSpannenderweise fehlt aber in beiden Versionen die if-Abfrage! Der leicht abgewandelte Code erzeugt ein besseres Ergebniss:

void testfunc(void)
{ int time;

while (1)
{
if (time > 1) time=1;
}
}

int main(void)
{
while(1);
return(0);
}bindet auch die Abfrage und die Zuweisung ein:

29 .LM2:
30 000a 8981 ldd r24,Y+1
31 000c 9A81 ldd r25,Y+2
32 000e 8230 cpi r24,2
33 0010 9105 cpc r25,__zero_reg__
34 0012 04F0 brlt .L3
35 0014 81E0 ldi r24,lo8(1)
36 0016 90E0 ldi r25,hi8(1)
37 0018 9A83 std Y+2,r25
38 001a 8983 std Y+1,r24
39 001c 00C0 rjmp .L3
Wieder wurde alles warnungs- und fehlerfrei übersetzt.

Gruß

mic

uwegw
20.07.2011, 15:48
Spannenderweise fehlt aber in beiden Versionen die if-Abfrage!

Was daran liegt, dass sie wegoptimiert wird...

@Siro: welchen Compiler und welche Compileroptionen verwendest du? Der gcc beispielsweise initalisiert alle Variablen automatisch mit Null und erzeugt dementsprechend auch keine Warnung.

uwegw
20.07.2011, 16:01
Mache ich folgendes:

void testfunc(void)
{ int time1;

if (time1 > 1) {time1--;}

}

void testfunc2(void)
{ int time2;

while (1)
{
if (time2 > 1) {time2--;}
}
}

int main(void)
{
int time3;
time3++;

testfunc();
testfunc2();
return(0);
}
gibt es mit GCC4.5.2 unter Windows/mingw und mit Option -Wall eine Warnung für time1 und time3, aber nicht für time2. Allerdings nur mit dem time1--;, sonst auch nicht (aber da schlägt dann ja die Optimierung zu)

sternst
20.07.2011, 18:56
Der gcc beispielsweise initalisiert alle Variablen automatisch mit Null und erzeugt dementsprechend auch keine Warnung.Sorry, aber das ist in Bezug auf nicht-statische lokale Variablen (und darum geht es hier) schlicht falsch.

Siro
21.07.2011, 15:06
Hallo uwegw:
Ich arbeite mit der IAR Embedded Workbench.

@radbruch
die if Abfragen fehlen weil sie wegoptimiert wurden.
Dies kannst Du aber verhindern indem Du vor die Variablen "volatile" schreibst

volatile int time;

Fazit:
Es scheinen also die Compiler unterschiedliche Warnings auszugeben. Ist mir im Prinzip egal,
ich hab nur lieber einen Warning mehr als einen zu wenig, weil dieser oft schon auf einen Fehler hinweist.

Danke Euch, daß Ihr es auch mal probiert habt.
Siro