Hallo Experten,
bin wider mal mit meinem Latein am Ende.
Habe folgenden Code und verstehe nicht warum die default Marke meines
Switch Blockes nicht ausgeführt wird. Jedenfalls sagt das AvrStudio beim
erstellen eines bookmark das dieser Teil vom Code der Optimierung zum
Opfergefallen ist.
1
voidRxProt(volatileuint8_tinput)
2
{
3
externprotoInProto[2];
4
staticuint8_tpos;
5
staticuint8_terror;
6
7
externvolatileuint8_tprotoflag;
8
staticuint8_t*ptr;
9
10
switch(pos)
11
{
12
default:// recive
13
if(input==START)
14
{
15
Proto[0].start=input;
16
Proto[1].start=input;
17
pos++;
18
}
19
break;
20
case1:
21
22
Proto[0].len=input;
23
Proto[1].len=input;
24
pos++;
25
break;
26
case2:
27
pos++;
28
switch(input)
29
{
30
case1:
31
ptr=&Proto[0];
32
protoflag|=(1<<RxCh1);
33
Proto[0].adress=input;
34
break;
35
case2:
36
ptr=&Proto[1];
37
protoflag|=(1<<RxCh2);
38
Proto[1].adress=input;
39
break;
40
default:
41
pos=0;
42
break;
43
}
44
break;
45
//case 1:
46
//case 2:
47
case3:
48
case4:
49
case5:
50
case6:
51
case7:
52
case8:
53
case9:
54
case10:
55
case11:
56
case12:
57
case13:
58
case14:
59
*(ptr+pos)=input;
60
pos++;
61
break;
62
case15:
63
*(ptr+pos)=input;
64
pos++;
65
//protoflag |= (1<<RxComp);
66
//t= CalcCRC16(dataRX,15);
67
if(CalcCRC16(ptr,15)!=0)//CalcCRC16(dataRX,15)
68
{
69
error++;
70
pos=0;
71
}
72
else
73
{
74
pos=0;
75
protoflag|=(1<<RxComp);
76
protoflag|=(1<<RxCh1);
77
RxLedPort^=(1<<RxLed);
78
}
79
}
80
}
Ich spreche vom zweitem Switch Block.
das input kommt vom Empfangsinterrupt.
Die Funktion RxProt wird auch im Empfangsinterrupt der Uart aufgerufen
Kann mir jemand auf die Sprünge helfen.
Wenn ich die Optimierung ausschalte dann Funktioniert das Ganze.
Ich habe zwar auf volatile gedacht aber leider kriege ich es nicht hin.
Vielen Dank für Eure Hilfe
Peter
Aus dem gezeigten Code-Ausschnitt lässt sich die Ursache nicht
ermitteln.
Reduziere den Code so weit wie möglich, so das er das Problem noch
zeigt, aber auch kompilierbar ist. Poste ihn als Anhang. Poste auch alle
Warnings die Du angezeigt bekommst.
Pier S. schrieb:> Jedenfalls sagt das AvrStudio beim> erstellen eines bookmark das dieser Teil vom Code der Optimierung zum> Opfergefallen ist.
das hat estmal nicht zu sagen. Macht denn der code noch was er soll?
Ganz allgemein kann man noch hinzufügen, das der Compiler aus Deinem
Quelltext geschlossen hat, das der Default-Fall nie eintreten kann.
Im allgemeinen gilt dieser Schluss auch. Die Ursache wird also in Deinem
Code liegen.
Danke für die Antworten.
Der Code ist Funktioniert mit Optimierung nicht mehr.
Fakt ist das die variable input mit Sicherheit nicht immer 1 oder 2 ist.
Input ist ja mit den Daten von der Uart gefühlt kann also von 0 bis 255
alles beinhalten.
Ich werde vrsuchen den Code zu verkleinern und zu Posten.
Danke für Eure Hilfe
Peter
Ps mit Sicherheit ligt der Fehler bei mir.
Noname schrieb:> Ich gehe übrigens davon aus, das Du im List-File nachgeschaut hast und> gesehen, das der Code für den Default-Fall tatsächlich nicht vorhanden> ist.
Ja im List_File kommt die default Marke nicht vor.
Peter
>Danke für die Antworten.
Bitte.
>Der Code ist Funktioniert mit Optimierung nicht mehr.
Ein Hinweis, das Du was anderes geschrieben hast, als Du denkst.
>Fakt ist das die variable input mit Sicherheit nicht immer 1 oder 2 ist.>Input ist ja mit den Daten von der Uart gefühlt kann also von 0 bis 255>alles beinhalten.
So das sich dann die Frage stellt, warum Du nicht alle 256 Möglichkeiten
im Switch berücksichtigt hast.
Abgesehen davon, kann es auch durch den Kontrollfluss möglich sein, das
der Wertebereich an der Stelle des Aufrufs der Funktion eingeschränkt
ist und der Compiler das aus dem Code statisch analysieren kann. Der
Eingabewertebereich allein ist nicht entscheidend.
>Ich werde vrsuchen den Code zu verkleinern und zu Posten.
Gut.
>Ps mit Sicherheit ligt der Fehler bei mir.
Nun, "mit Sicherheit" ist vermutlich auch übertrieben, aber er liegt
wahrscheinlich bei Dir.
Noname schrieb:> So das sich dann die Frage stellt, warum Du nicht alle 256 Möglichkeiten> im Switch berücksichtigt hast.
Ich möchte ja bei allen andern Daten außer bei 1 und 2 abbrechen indem
ich pos auf 0 setze.
Also habe ich es in einer gewissen Art und Weise alle Möglichkeiten
berücksichtigt.
Peter
Hoffe das ich den Code bald soweit habe das ich in Posten kann
@ Pier S.
>Ich möchte ja bei allen andern Daten außer bei 1 und 2 abbrechen indem>ich pos auf 0 setze.>Also habe ich es in einer gewissen Art und Weise alle Möglichkeiten>berücksichtigt.
Ja, das hast Du. Meine Frage war nicht relevant. Ein Irrtum meinerseits.
Es bleibt die Möglichkeit das aus dem Kontrollfluss erkennbar ist, das
andere Fälle ausser 1 und 2 nicht eintreten können.
rmf schrieb:> Bin zwar nicht der C Guru, aber könnte es sein das der Compiler so> komisch reagiert weil in deinem Case 15 das Break am Ende fehlt ?>> gruß Udo
Ja genau das ist es.
Vielen Vielen Dank
Schönes Wochenende
Peter
Das ergibt keinen Sinn. Hinter dem letzten Fall eines Switch-Statements
muss kein "break" stehen. Es wegzulassen ist zwar nicht anzuraten, aber
formal notwendig ist es nicht.
Sehe ich auch so. Das fehlende break kann auch nicht bewirken das der
Code für den Default-Fall in dem untergeordneten switch fehlt.
Da muss irgendein anderes Problem existieren.
In deinem Zip-File:
Ist das mit oder ohne Optimierungen compiliert?
Im LSS-File ist der fragliche Code vorhanden und auch die Sprungleiste
sieht auf den ersten Blick vernünftig aus.
(Es kommt zwar vor, dass Compiler fehlerhaft ausgeliefert werden. Aber
es ist selten. In >95% aller Fälle hast du den Fehler im Programm selbst
programmiert. Compilerfehler würd ich für mich erst mal immer
ausschliessen und den Fehler erst mal im Code suchen)
>hab mich zu früh gefreut das Problem ist noch vorhanden.
Ja. Davon sind A.K. und ich ausgegangen.
OK. Code ist vorhanden. Aber ich habe keine Lust das Ganze Gewusel nun
noch auseinander zu nehmen. Vielleicht ja jemand anders.
Falls sich keiner findet der nicht so faul ist wie ich, reduziere den
Code soweit, das nur das allernotwendigste vorhanden ist um den Fehler
reproduzieren zu können. Aber er muss kompilierbar sein.
Was ist eigentlich mit den Warnungen? Keinerlei Warnungen angezeigt?
Noname schrieb:>>hab mich zu früh gefreut das Problem ist noch vorhanden.>> Ja. Davon sind A.K. und ich ausgegangen.>> OK. Code ist vorhanden. Aber ich habe keine Lust das Ganze Gewusel nun> noch auseinander zu nehmen. Vielleicht ja jemand anders.
Geht mir eigentlich genauso.
Vor allen Dingen dann, wenn ich erst mal das Mischmasch aus
Tabultor-Einrückungen und Leerzeichen-Einrückungen auseinandersortieren
und aneinander angleichen muss, um zu sehen ob die { - } Hierarchien
korrekt sind und mit der vorhandenen Einrückung übereinstimmen.
Ich denke, der fragliche Code wird bei eingeschalteter Optimierung schon
irgendwo sein. Nur hat der Compiler das eben ein wenig umgestellt, so
dass er nicht mehr auf den ersten Blick zu finden ist. In a nutshell:
Ich denke, bei der Suche warum der Code in der optimierten Version nicht
funktioniert, wird da der falsche Baum angebellt.
Karl-Heinz ist da. Dann wird alles gut. :-)
>Im LSS-File ist der fragliche Code vorhanden und auch die Sprungleiste>sieht auf den ersten Blick vernünftig aus.
Oh je. Da haben wir doch nach gefragt und der TO hat geschrieben, das
der Code nicht vorhanden ist.
Beitrag "Re: default von Switch wird nicht abgearbeitt"
Noname schrieb:> Karl-Heinz ist da. Dann wird alles gut. :-)
Nicht wirklich. :-)
Ich hab hier auf dem PC kein AVR-Studio bzw. AVR-Gcc und ich hab auch
keine Lust da extra einen zu installieren (darf ich auch gar nicht).
Also muss Codeanalyse ran. Die Bereitschaft dazu sinkt aber gewaltig,
wenn ich erst mal wie ein Wilder umformatieren muss, um überhaupt etwas
zu sehen.
Karl-Heinz schrieb:
>...wird da der falsche Baum angebellt.
Vermutlich. Habe mir nochmal den Eröffnungspost durchgelesen.
>Habe folgenden Code und verstehe nicht warum die default Marke meines>Switch Blockes nicht ausgeführt wird.>Jedenfalls sagt das AvrStudio beim>erstellen eines bookmark das dieser Teil vom Code der Optimierung zum>Opfergefallen ist.
Das eine hat mit dem anderen nichts zu tun. Durch die Optimierung kann
es schon sein, das der dahinterliegende Asm-Code irgendwo und noch
zerfasert herumliegt, so das der Debugger meint er könne die Adresse
nicht lokalisieren.
Das müsste jetzt nochmal geklärt werden:
1. Funktioniert der Code wirklich nicht.
oder
2. Kann man nur an dem Default keinen Breakpoint (Bookmark ???) setzen.
Karl Heinz Buchegger schrieb:> Vor allen Dingen dann, wenn ich erst mal das Mischmasch aus> Tabultor-Einrückungen und Leerzeichen-Einrückungen auseinandersortieren
4er Tabs einstellen, dann passt es.
Naja. Zwischendurch werkel ich hier gerade an ner STM32F4-Geschichte
herum. Habe gerade keine Lust so tief einzusteigen. Am Ende ist es
ohnehin ein Missverständnis oder ein fehlendes volatile oder ne
Initialisierung, das/die man schon mal nur per Augenschein sehen kann.
Aber nicht in dem Verhau eben.
Also ich sagte ja das ich auch der Überzeugung bin das der Fehler bei
mir liegt.
Habe den betreffenden Teil des LSS-File in ein Txt File kopiert und ich
sehe das Default nicht behandelt.
Werde den Code nochmals versuchen zu verkleinern.
Gruß
Peter
Der Code funktioniert mit Optimierung nicht!
Um den Fehler zu finden (Crc ist immer Falsch ) ist mir aufgefallen das
der Defaultblock nicht erreicht wird.
Hingegen ohne Optimierung geht der Code und es wird auch dieser
Defaultblock
erreicht.
Gruß
Peter
>Also ich sagte ja das ich auch der Überzeugung bin das der Fehler bei
mir liegt.
Ist schon gut. Ist nur die übliche professionelle Brummigkeit. :-) Denk
Dir nichts dabei.
Pier S. schrieb:> Der Code funktioniert mit Optimierung nicht!> Um den Fehler zu finden (Crc ist immer Falsch ) ist mir aufgefallen das> der Defaultblock nicht erreicht wird.
Im Debugger?
Das heißt nicht viel. Daran kannst du dich nicht orientieren.
Der Optimizer wird den Code umgestellt haben, so dass ihn der Debugger
nicht mehr findet.
Karl Heinz Buchegger schrieb:> Im Debugger?>> Das heißt nicht viel. Daran kannst du dich nicht orientieren.> Der Optimizer wird den Code umgestellt haben, so dass ihn der Debugger> nicht mehr findet.
Ja im Debugger.
Wie soll ich dann weiter vorgehen?
Danke Gruß
Peter
Pier S. schrieb:> Ich spreche vom zweitem Switch Block.
1) Der 2. switch (input) wird nur in case 2 des äusseren switch (input)
betreten, d.h. im inneren ist input immer 2. Ergo: der default-Fall
wird nie gebraucht, ditto case 1.
2) Mach das volatile am Parameter weg, das ist Käse
3) ptr hat den falschen Typ. Proto[0] ist vom Typ protoIn, &Proto[0]
demnach vom Typ protoIn* und nicht vom Typ uint8_t*.
4) externe Deklarationen gehören bis auf seltene Ausnahmen in einen
Header, nicht ins C-Modul wo Inkompatibilitäten nicht auffallen.
5) case 15 fehlt ein break. Ist momentan zwar egal, bei Umstrukturierung
oder Erweiterung des Codes wirst du dir aber den Wolf suchen.
Ich habe folgenden Code verwendet, weil sonst Deklarationen fehlen:
1
#include<stdint.h>
2
3
#define START 0
4
5
typedefstruct
6
{
7
uint8_tstart;
8
uint8_tlen;
9
uint8_tadress;
10
}protoIn;
11
12
enum{RxLed,RxCh1,RxCh2,RxComp};
13
14
#define RxLedPort *((uint8_t volatile*) 42)
15
16
voidRxProt(uint8_tinput)
17
{
18
externprotoInProto[2];
19
staticuint8_tpos;
20
staticuint8_terror;
21
22
externvolatileuint8_tprotoflag;
23
staticuint8_t*ptr;
24
25
switch(pos)
26
{
27
default:// recive
28
if(input==START)
29
{
30
Proto[0].start=input;
31
Proto[1].start=input;
32
pos++;
33
}
34
break;
35
36
case1:
37
38
Proto[0].len=input;
39
Proto[1].len=input;
40
pos++;
41
break;
42
43
case2:
44
pos++;
45
switch(input)
46
{
47
case1:
48
ptr=&Proto[0];
49
protoflag|=(1<<RxCh1);
50
Proto[0].adress=input;
51
break;
52
case2:
53
ptr=&Proto[1];
54
protoflag|=(1<<RxCh2);
55
Proto[1].adress=input;
56
break;
57
default:
58
pos=0;
59
break;
60
}
61
break;
62
//case 1:
63
//case 2:
64
case3:
65
case4:
66
case5:
67
case6:
68
case7:
69
case8:
70
case9:
71
case10:
72
case11:
73
case12:
74
case13:
75
case14:
76
*(ptr+pos)=input;
77
pos++;
78
break;
79
case15:
80
*(ptr+pos)=input;
81
pos++;
82
//protoflag |= (1<<RxComp);
83
//t= CalcCRC16(dataRX,15);
84
if(CalcCRC16(ptr,15)!=0)//CalcCRC16(dataRX,15)
85
{
86
error++;
87
pos=0;
88
}
89
else
90
{
91
pos=0;
92
protoflag|=(1<<RxComp);
93
protoflag|=(1<<RxCh1);
94
RxLedPort^=(1<<RxLed);
95
}
96
}
97
}
hm...
Das äussere swicth ist auf pos :-/, da war ich oben zu fix...
Dafür entält der erzeugte Code Instruktionen für den default des inneren
switch :-))
Johann L. schrieb:> 1) Der 2. switch (input) wird nur in case 2 des äusseren switch (input)> betreten, d.h. im inneren ist input immer 2. Ergo: der default-Fall> wird nie gebraucht, ditto case 1.
Der äußere switch hat pos als Parameter also kann input alles möglichen
Werte haben .
Beim Rest hast du sicher recht werde ich ändern
Danke
Gruß
Peter
Hm. Der Code geht ohne Optimierung aber nicht mit.
Guck Dir alle in interrupts benutzten Variablen an ob sie wirklich
volatile sind.
>1) Der 2. switch (input) wird nur in case 2 des äusseren switch (input)> betreten, d.h. im inneren ist input immer 2. Ergo: der default-Fall> wird nie gebraucht, ditto case 1.
Der äussere switch hängt nicht von input ab sondern von pos.
pos ist nicht initialisiert!
Gar keine Warnings?
Pier S. schrieb:> Wie soll ich dann weiter vorgehen?
Hast du eine Möglichkeit, dir irgendwo Ausgaben machen zu lassen? (LCD,
noch ne UART)
Wenn ja: Einen kompletten Frame da mal ausgeben lassen und ansehen, was
du zurückbekommst.
Wenn nein: warum hast du sowas nicht? Programmentwicklung ohne sich auf
der realen Hardware was ausgeben zu lassen hat immer was von 'Stochern
im Nebel'
1
typedefvolatilestruct// 15 Byte
2
{
3
uint8_tstart;
4
uint8_tlen;
5
uint8_tadress;
6
intanalog[4];
7
uint8_toutput;
8
uint8_tcrcerror;
9
unsignedintcrc;
10
}protoIn;
Welche Aussage hat da der Member crcerror?
Ist das die Rückmeldung vom Gerät, dass deine Anfrage einen CRC-Error
hatte?
Pier S. schrieb:> Johann L. schrieb:>> 1) Der 2. switch (input) wird nur in case 2 des äusseren switch (input)>> betreten, d.h. im inneren ist input immer 2. Ergo: der default-Fall>> wird nie gebraucht, ditto case 1.>> Der äußere switch hat pos als Parameter also kann input alles möglichen> Werte haben .
Hab mich schon selbst korrigiert:
Johann L. schrieb:> Das äussere swicth ist auf pos :-/, da war ich oben zu fix...>> Dafür entält der erzeugte Code Instruktionen für den default des inneren> switch :-))
Der default-Zweig wird auch vom Compiler erzeugt.
Hier der entscheidende Ausschnitt aus dem lss-File.
Der Compiler hat halt eine andere Stelle im Code gefunden, der die
gleiche Funktion hat.
Das default-Label ist dadurch verlorengegangen, der Code ist aber da.
Karl Heinz Buchegger schrieb:> Hast du eine Möglichkeit, dir irgendwo Ausgaben machen zu lassen?> Wenn ja: Einen kompletten Frame da mal ausgeben lassen und ansehen, was> du zurückbekommst.
Ja habe ich und die Daten kommen auch richtig an.Ohne Optimierung ist
mein Programm ja auch der Meinung das die Daten richtig sind.
Karl Heinz Buchegger schrieb:> Welche Aussage hat da der Member crcerror?> Ist das die Rückmeldung vom Gerät, dass deine Anfrage einen CRC-Error> hatte?
Ja damit sieht man ob die Gegenstelle Fehler beim Empfangen hatte.
Uwe Nagel schrieb:> Der default-Zweig wird auch vom Compiler erzeugt.> Hier der entscheidende Ausschnitt aus dem lss-File.> Der Compiler hat halt eine andere Stelle im Code gefunden, der die> gleiche Funktion hat.> Das default-Label ist dadurch verlorengegangen, der Code ist aber da.
Also so wie Karl Heinz sagte ich belle den falschen Baum an!
Pier S. schrieb:> Karl Heinz Buchegger schrieb:>> Hast du eine Möglichkeit, dir irgendwo Ausgaben machen zu lassen?>> Wenn ja: Einen kompletten Frame da mal ausgeben lassen und ansehen, was>> du zurückbekommst.>> Ja habe ich und die Daten kommen auch richtig an.Ohne Optimierung ist> mein Programm ja auch der Meinung das die Daten richtig sind.
Der Frame den du zurückbekommst ist korrekt? (Ausgeben lassen, sieht das
plausibel aus?)
Hast du die CRC mal händisch nachgerechnet?
Andere Frage: Woran merkst du eigentlich, dass 'es nicht funktioniert'.
Beim Drüberschauen hab ich nichts ausmachen können, das spezifisch auf
einen CRC Fehler reagiert (ausser der static error Variablen). Du hast
du noch eine Timeout-Sache inkludiert, kann es sein, dass die anschlägt?
Ich merke am RxComp Flag in der main wenn Daten richtig angekommen sind.
Und dieses Flag bleibt mit Optimierung aus.
Die CRC habe ich auch nachgerechnet. Bin ziemlich ratlos.
Gruß
Peter
Auf protoflag (in dem auch RxComp liegt) wird sowohl im Main- wie auch
auch im ISR-Kontext schreibend (bzw. RMW) zugegriffen. Die Main-Zugriffe
sind jedoch nicht geschützt.
Stefan Ernst schrieb:> Auf protoflag (in dem auch RxComp liegt) wird sowohl im Main- wie auch> auch im ISR-Kontext schreibend (bzw. RMW) zugegriffen. Die Main-Zugriffe> sind jedoch nicht geschützt.
Ja mache ich so. Aber ich verstehe nicht was das mit meinem Problem zu
tun hat.
Bitte um Erklärung
Danke gruß
Peter
Hallo,
nach einer längeren Pause habe ich wider Zeit gefunden an meinem
Programm weiter zu machen.
Ich glaube ich mache einen bösen Fehler mit den verwendeten Zeiger.
Ich vermute das ich mir die Daten meines Structur Array zerschieße.
1
typedefvolatilestruct// 15 Byte
2
{
3
uint8_tstart;
4
uint8_tlen;
5
uint8_tadress;
6
intanalog[4];
7
uint8_toutput;
8
uint8_tcrcerror;
9
unsignedintcrc;
10
}protoIn;
11
12
voidRxProt(volatileuint8_tinput)
13
{
14
15
staticuint8_tpos;
16
staticuint8_terror;
17
18
19
staticuint8_t*ptr;
20
21
switch(pos)
22
{
23
default:// recive
24
if(input==START)
25
{
26
test[0].start=input;
27
test[1].start=input;
28
pos++;
29
}
30
break;
31
case1:
32
test[0].len=input;
33
test[1].len=input;
34
pos++;
35
break;
36
case2:
37
pos++;
38
switch(input)
39
{
40
case1:
41
ptr=&test[0];
42
protoflag|=(1<<RxCh1);
43
test[0].adress=input;//Proto[0].adress= input;
44
break;
45
case2:
46
ptr=&test[1];
47
protoflag|=(1<<RxCh2);
48
test[1].adress=input;//Proto[1].adress= input;
49
break;
50
default:
51
pos=0;
52
break;
53
}
54
break;
55
//case 1:
56
//case 2:
57
case3:
58
case4:
59
case5:
60
case6:
61
case7:
62
case8:
63
case9:
64
case10:
65
case11:
66
case12:
67
case13:
68
case14:
69
*(ptr+pos)=input;
70
pos++;
71
break;
72
case15:
73
*(ptr+pos)=input;
74
pos++;
75
//protoflag |= (1<<RxComp);
76
//t= CalcCRC16(dataRX,15);
77
if(CalcCRC16(ptr,15)!=0)//CalcCRC16(dataRX,15)
78
{
79
error++;
80
pos=0;
81
}
82
else
83
{
84
pos=0;
85
protoflag|=(1<<RxComp);
86
//protoflag |= (1<<RxCh1);
87
RxLedPort^=(1<<RxLed);
88
}
89
break;
90
}
91
}
Ich habe den Teil wo ich mit den Zeigern Arbeite nochmal beigelegt.
Ich hoffe jemand kann mir helfen den Fehler zu finden.
Vielen Dank im voraus
Peter
Mann o Mann bin ich blöd die Structur hat 15 Byte und ich zähle munter
bis 16 und überschreibe mir die Daten vom nächsten Datensatz.
Vielen Dank für Eure Hilfe und Geduld
Peter
Karl Heinz Buchegger schrieb:> Ich hab hier auf dem PC kein AVR-Studio bzw. AVR-Gcc und ich hab auch> keine Lust da extra einen zu installieren (darf ich auch gar nicht).
Du darfst keine Software installieren? Das ist als Entwickler doch wohl
unumgänglich...
Pier S. schrieb:> Mann o Mann bin ich blöd die Structur hat 15 Byte und ich zähle munter> bis 16 und überschreibe mir die Daten vom nächsten Datensatz.
Das erinnert mich an einen Fehler, den ich diese Woche bei einem Code
Review gefunden habe: Jemand deklariert ein
int array[17];
und einige Zeilen weiter unten steht dann:
array[17] = 0;
Da kriegt man schon ein wenig Kopfweh...
Mark Brandis schrieb:> Das erinnert mich an einen Fehler, den ich diese Woche bei einem Code> Review gefunden habe: Jemand deklariert ein> int array[17];> und einige Zeilen weiter unten steht dann:> array[17] = 0;>> Da kriegt man schon ein wenig Kopfweh...
... und die "magic numbers" hast du nicht angemeckert?