Hallo, ich habe Schwierigkeiten bei der Interpretation dieses
Codestücks:
1
voidDisp_Write_Text(charcode*msg)
2
{
3
charz;
4
while(z=*msg++)
5
{
6
Disp_Write_Data(z);
7
}
8
}
Aufgerufen wird zB mit Disp_Write_Text ("Hallo Forum");
Offensichtlich wird bei der Zuweisung von z auch das Stringende \0
erkannt.
Aber ist das dokumentiertes Standard-C oder Spezial-Geheim-Tricky?
Marius Wensing schrieb:> Ja, das while (z = *msg++) ist eine Zuweisung mit gleichzeitiger Abfrage> von z.
Sowas ähnliches kann man für eine Flankenerkennung verwenden:
1
if(tastealt!=taste&&(tastealt=taste)){
2
/*steigende Flanke*/
3
}
Auch hier ist ein Vergleich und eine Zuweisung in der Abfrage...
null schrieb:> ps Danke fürs Editieren
Keine Ursache. War eh' grad da... ;-)
Peter II schrieb:> warum nicht? Da gibt es eigentlich keinen Spielraum für> fehlinterpretationen.
Ja und nein; Das ist zwar so klar Lesbar, aber s ist eine nicht
garantierte Übersetzung des Compilers.
Es kann sein das Dein Compiler das richtige macht, aber ein anderer
Compiler eventuell etwas anderes daraus macht.
Misra würde mehrere Fehler setzen.
1. das "=" in einer Abfrage
2. fehlende Klammern
3. eventuell ein implizierter Vergleich da der Vergleichsoperator fehlt
Die Fehlernummern weiß ich jetzt aber nicht auswendig.
z = *msg;
while ( z != NULL )
{
Disp_Write_Data (z);
z = *msg++;
}
das hier sollte Fehlerfrei sein, und außerdem auch klarer Lesbar.
Ja ich weiß es sind ein paar Zeichen mehr in die Tastatur zu hauen aber
besser ist das schon.
...würde ich in C niemals so programmieren :-)
Wenn dann eher
while(*msg != '\0') {
Display_Write_Data( *msg);
msg++;
}
Wobei die Form *(msg++) wirklich sehr gebräuchlich ist, also wer
while(*msg != '\0') {
Display_Write_Data( *(msg++) );
}
nicht versteht, sollte lieber nicht in C programmieren. Wenn der
Compiler halbwegs vernünftig ist, sollte der Umweg mit der Variablen
keine Verbesserung bringen. Er hat ja eh den Pointer in einem der
Register...
Und anstelle von NULL bevorzuge ich ein '\0', da es nochmal klar macht,
dass es sich um einen Character handelt.
Grüße
Markus
Ralph schrieb:> z = *msg;> while ( z != NULL )> {> Disp_Write_Data (z);> z = *msg++;> }>>> das hier sollte Fehlerfrei sein
Nein (MISRA-C:2004):
Rule 17.4 (required): Array indexing shall be the only allowed form of
pointer arithmetic.
Ralph schrieb:> z = *msg;> while ( z != NULL )> {> Disp_Write_Data (z);> z = *msg++;> }>>> das hier sollte Fehlerfrei sein, und außerdem auch klarer Lesbar.
Weder noch ;-)
In deiner Version wird das erste Zeichen zweimal ausgegeben.
Ralph schrieb:> Peter II schrieb:>> warum nicht? Da gibt es eigentlich keinen Spielraum für>> fehlinterpretationen.>> Ja und nein; Das ist zwar so klar Lesbar, aber s ist eine nicht> garantierte Übersetzung des Compilers.> Es kann sein das Dein Compiler das richtige macht, aber ein anderer> Compiler eventuell etwas anderes daraus macht.
Wenn ein Compiler schon so simple Dinge nicht hinbekommt, dann würde ich
es als fahrlässig bezeichnen, den für sicherheitskritische Programme zu
verwenden. Laut ISO C gibt es da nämlich nur genau eine Möglichkeit, das
zu interpretieren.
Also das würde ich das ja alles gleich als for-Schleife schreiben. Finde
ich deutlich besser zu lesen:
Juergen schrieb:> i = 0;> while ( msg[i] != 0 )> {> Disp_Write_Data ( msg[i] );> i++;> }
for (i = 0; msg[i] != '\0'; i++)
{
Disp_Write_Data(msg[i]);
}
null schrieb:> void Disp_Write_Text (char code *msg)> {> char z;> while (z = *msg++)> {> Disp_Write_Data (z);> }> }
for (; *msg; msg++)
{
Disp_Write_data(*msg);
}
Juergen schrieb:> while ( msg[i] != 0 )> {>> Disp_Write_Data ( msg[i] );> i++;> }
Mal ehrlich, ne Runde Klammer gefolgt von einem Leerzeichen, bzw. ein
Leerzeichen gefolgt von einer runden Klammer ist doch ekelerregend.
Kernies Bruder schrieb:> Mal ehrlich, ne Runde Klammer gefolgt von einem Leerzeichen, bzw. ein> Leerzeichen gefolgt von einer runden Klammer ist doch ekelerregend.
Es gibt wohl wenig über das mehr diskutiert als über Styleguides.
Rolf Magnus schrieb:>> Also das würde ich das ja alles gleich als for-Schleife schreiben. Finde> ich deutlich besser zu lesen:>> Juergen schrieb:>> i = 0;>> while ( msg[i] != 0 )>> {>> Disp_Write_Data ( msg[i] );>> i++;>> }>> for (i = 0; msg[i] != '\0'; i++)> {> Disp_Write_Data(msg[i]);> }
Das ist Geschmackssache.
Ich nehme for-Schleifen eigentlich nur,
wenn da über einen festen Bereich iteriert wird.
Juergen schrieb:> Das ist Geschmackssache.> Ich nehme for-Schleifen eigentlich nur,> wenn da über einen festen Bereich iteriert wird.
Mache ich auch so. Deshalb nehme ich dort ja eine for-Schleife. ;-)
Ich vermute aber, daß wir den "über einen festen Bereich iterieren"
unterschiedlich definieren.
Martin Wende schrieb:> Rolf Magnus schrieb:>> for (i = 0; msg[i] != '\0'; i++)>> {>> Disp_Write_Data(msg[i]);>> }>> WTF?
Willst du damit irgendwas sagen?
Rufus Τ. Firefly schrieb:> Markus M. schrieb:>> while(*msg != '\0')>> while (*msg)>> macht genau das gleiche.
MISRA-C:2004 Rule 13.2 (advisory):
Tests of a value against zero should be made explicit,
unless the operand is effectively Boolean.
Juergen schrieb:> Rufus Τ. Firefly schrieb:>> Markus M. schrieb:>>> while(*msg != '\0')>>>> while (*msg)>>>> macht genau das gleiche.>> MISRA-C:2004 Rule 13.2 (advisory):> Tests of a value against zero should be made explicit,> unless the operand is effectively Boolean.
Ein Grund mehr für mich, niemals ein Projekt anzunehmen, in dem MISRA
gefordert wird.
Karl Heinz Buchegger schrieb:> in Grund mehr für mich, niemals ein Projekt anzunehmen, in dem MISRA> gefordert wird.
Besonders Begabte können auch MISRA-konformen Spaghetti-Code
fabrizieren...
Bei Stringverarbeitung verwende ich eher while-Schleifen als
for-Schleifen. Insbesondere wenn ich nicht abschätzen kann wie lang die
Zeichenkette denn nun ist, bringt mir die while-Schleife den Vorteil das
ich mir keine Gedanken um den Datentyp der Zählvariablen machen muss.
Ist der Wertebereich der Variablen zu klein baut man sich eine super
Endlosschleife.
Juergen schrieb:> Rufus Τ. Firefly schrieb:>> Markus M. schrieb:>>> while(*msg != '\0')>>>> while (*msg)>>>> macht genau das gleiche.>> MISRA-C:2004 Rule 13.2 (advisory):> Tests of a value against zero should be made explicit,> unless the operand is effectively Boolean.
Mal so aus Interesse: Wann ist er denn "effectively Boolean" und woran
erkennt das ein MISRA-Validierungs-Tool? Abgesehen davon scheint es ja
keine Vorgabe, sondern nur eine Empfehlung zu sein.
M. K. schrieb:> Bei Stringverarbeitung verwende ich eher while-Schleifen als> for-Schleifen. Insbesondere wenn ich nicht abschätzen kann wie lang die> Zeichenkette denn nun ist, bringt mir die while-Schleife den Vorteil das> ich mir keine Gedanken um den Datentyp der Zählvariablen machen muss.> Ist der Wertebereich der Variablen zu klein baut man sich eine super> Endlosschleife.
Wenn man Pointerarithmetik (kompliziertes Wort) in die for-Schleife
packt braucht man keine Zählvariable... OK, MISRA mag das nicht, aber
davon abgesehen. for und while sind doch nur 2 Schreibweisen für das
gleiche Zeug.
Karl Heinz Buchegger schrieb:> Ein Grund mehr für mich, niemals ein Projekt anzunehmen, in dem MISRA> gefordert wird.
Was ist so schlimm an explizit formuliertem, leicht lesbarem Code?
Ich verwend auf controllern jeweils meine eigenen Stringdefinitionen, wo
das erste Byte die Laenge angibt. Da weiss man wenigsten sofort wie
lange das Ding ist.
M. K. schrieb:> Bei Stringverarbeitung verwende ich eher while-Schleifen als> for-Schleifen. Insbesondere wenn ich nicht abschätzen kann wie lang die> Zeichenkette denn nun ist, bringt mir die while-Schleife den Vorteil das> ich mir keine Gedanken um den Datentyp der Zählvariablen machen muss.
Warum sollten sich for und while da unterscheiden?
Rolf Magnus schrieb:> Warum sollten sich for und while da unterscheiden?
Hat er doch erklärt! Wer lesen kann, ist klar im Vorteil:
"...bringt mir die while-Schleife den Vorteil das
ich mir keine Gedanken um den Datentyp der Zählvariablen machen muss."
Kernies Bruder schrieb:> Rolf Magnus schrieb:>> Warum sollten sich for und while da unterscheiden?>> Hat er doch erklärt!
Hat er nicht.
> "...bringt mir die while-Schleife den Vorteil das> ich mir keine Gedanken um den Datentyp der Zählvariablen machen muss."
Und genau darauf habe ich gefragt, warum sich da for und while
unterscheiden sollten. Wenn ich eine Zählvariable benutze, muß der
Datentyp groß genug sein, um jeden Fall abdecken zu können, wenn nicht
dann nicht. Das hat aber nichts damit zu tun, ob ich eine for- oder eine
while-Schleife verwende.
Marwin schrieb:> Karl Heinz Buchegger schrieb:>> Ein Grund mehr für mich, niemals ein Projekt anzunehmen, in dem MISRA>> gefordert wird.>> Was ist so schlimm an explizit formuliertem, leicht lesbarem Code?
Ich find den Code eben nicht leicht lesbar.
void lcd_string( const char* str )
{
while( *str )
lcd_char( *str++ );
}
das ist für MICH leicht lesbar (subjektive Empfindung). Kurz, aber auch
nicht zu kurz. Kein unnützer Firlefanz mit zusätzlichen Variablen oder
Vergleichen, die zusätzliche Fehlerquellen darstellen, weil man sie
verbocken kann.
for und while unterscheiden sich lediglich in der Schreibweise.
for (INIT; CONDITION; REPEAT)
{
...
}
lässt sich immer als
INIT;
while (CONDITION)
{
...
REPEAT;
}
schreiben, wobei INIT und REPEAT optional sind. Ein einziger
klitzekleine Unterschied fällt mir ein: CONDITION ist bei der
for-Schleife ebenso optional, bei der while-Schleife jedoch zwingend
anzugeben.
troll schrieb:> for und while sind doch nur 2 Schreibweisen für das> gleiche Zeug.
Ganz und gar nicht. Eine Programmiersprache welche als Konstrollstruktur
NUR for-Schleifen hätte, wäre nicht Turing-Vollständig. Wohingegen nur
while, oder auch nur goto, Turing-Vollständig wäre.
gruß cyblord
cyblord ---- schrieb:> troll schrieb:>> for und while sind doch nur 2 Schreibweisen für das>> gleiche Zeug.>> Ganz und gar nicht. Eine Programmiersprache welche als Konstrollstruktur> NUR for-Schleifen hätte, wäre nicht Turing-Vollständig.
Jetzt musst du aber dazu sagen, welche 'for-Schleifen' du meinst.
Denn die C-Version hat ja mit dem, was man in anderen
Programmiersprachen unter 'FOR' versteht eigentlich nur das
Schlüsselwort gemeinsam.
Ja das stimmt natürlich. In der Theorie ist eine for-Schleife dadurch
definiert dass ihre maximale Iterationsanzahl im vorraus bekannt ist und
festgelegt werden muss. In C ist das schon etwas anderst.
gruß cyblord
Karl Heinz Buchegger schrieb:> das ist für MICH leicht lesbar (subjektive Empfindung). Kurz, aber auch> nicht zu kurz. Kein unnützer Firlefanz mit zusätzlichen Variablen oder> Vergleichen, die zusätzliche Fehlerquellen darstellen, weil man sie> verbocken kann.
Du meinst also, ein if( *blah) ist sicherer als ein if( blah != 0)?
Manchen Hackern kann man einfach nicht helfen, die sind viel zu tief in
ihrer Hackerwelt versumpft...
Marwin schrieb:> Karl Heinz Buchegger schrieb:>> das ist für MICH leicht lesbar (subjektive Empfindung). Kurz, aber auch>> nicht zu kurz. Kein unnützer Firlefanz mit zusätzlichen Variablen oder>> Vergleichen, die zusätzliche Fehlerquellen darstellen, weil man sie>> verbocken kann.>> Du meinst also, ein if( *blah) ist sicherer als ein if( blah != 0)?
Es sind 2 Elemente weniger, bei denen man sich vertun kann
anstatt dem != ein == schreiben
anstatt dem 0 einen anderen Wert angeben
> Manchen Hackern kann man einfach nicht helfen, die sind viel zu tief in> ihrer Hackerwelt versumpft...
Wie du meinst.
Es gibt wohl kaum einen Fehler, den ich nicht schon vor langer langer
Zeit schon mal gemacht habe. Und im Laufe der Zeit hat sich
herausgestellt, dass in C weniger des öfteren mehr ist. Schreib ich kein
!= oder == weil ich es nicht brauche UND der Ausdruck dabei nicht an
Klarheit verliert weil er kurz genug ist, dann kann ich mich dabei auch
nicht vertippen. Ganz einfach.
Die Kunst liegt in der sinnvollen Gratwanderung und nicht darin Dogmen
aufzuhäufen, die nur deswegen existieren, weil der Regel-Erfinder sich
vor etwas gefürchtet hat oder es bei anderen gesehen hat, die aus einer
gewissen Schludrigkeit heraus immer die gleichen Fehler machen ohne
daraus zu lernen.
Und deswegen mag ich MISRA nicht.
Es suggeriert eine Sicherheit, die nicht existiert.
Wer sein Werkzeug beherrscht, programmiert mit MISRA um keinen Deut
besser oder fehlerfreier als ohne.
Marwin schrieb:> Du meinst also, ein if( *blah) ist sicherer als ein if( blah != 0)?
Jepp. Du kannst kein "!" vergessen und auch nicht aus Versehen '0' statt
'\0' schreiben. Lesbarer ist die kurze Variante allemal.
> Manchen Hackern kann man einfach nicht helfen, die sind viel zu tief in> ihrer Hackerwelt versumpft...
Mit Hackern oder "hacken" hat das nichts zu tun. Eher mit dem optimalen
Einsatz eines Werkzeugs.
Juergen schrieb:> MISRA-C:2004 Rule 13.2 (advisory):> Tests of a value against zero should be made explicit,> unless the operand is effectively Boolean.
Da in C die Ergebnisse von Vergleichs- und logischen Operationen den
Datentyp int haben, sollte man nach MISRA also diese Abfrage
1
if(n>=0&&n<=9)
2
...
durch diese
1
if((((n>=0)!=0)&&((n<=9)!=0))!=0)
2
...
ersetzen (natürlich mit Klammern um sämtliche Teilausdrücke).
Ja, so wird die Sache wirklich übersichtlich, und Fehler wird bei dieser
Schreibweise sicher auch niemand machen ;-)
Yalu X. schrieb:> Ja, so wird die Sache wirklich übersichtlich, und Fehler wird bei dieser> Schreibweise sicher auch niemand machen ;-)
Ja, und selbst wenn: Dann wir das im Unit-Test, Integrations-Test,
System-Test, im Review und spätestens in der FMEA ;)
Karl Heinz Buchegger schrieb:>> Was ist so schlimm an explizit formuliertem, leicht lesbarem Code?>> Ich find den Code eben nicht leicht lesbar.>> void lcd_string( const char* str )> {> while( *str )> lcd_char( *str++ );> }>> das ist für MICH leicht lesbar (subjektive Empfindung).
Aber genau darum geht es NICHT!
Es geht nicht darum, was für einen einzelnen Programmierer leicht
verständlich ist. Es geht darum, dass alle in einem Projekt bzw. in
einer Firma nach den gleichen Regeln (Codierrichtlinien) programmieren.
Frank M. schrieb:> Marwin schrieb:>> Manchen Hackern kann man einfach nicht helfen, die sind viel zu tief in>> ihrer Hackerwelt versumpft...>> Mit Hackern oder "hacken" hat das nichts zu tun. Eher mit dem optimalen> Einsatz eines Werkzeugs.
Und die Leute, die nach ihren eigenen Regeln programmieren wollen, sind
die die Tools einsetzen (z.B. zur statischen Codeanalyse)? Doch wohl
eher gerade nicht.
Rolf Magnus schrieb:> M. K. schrieb:>> Bei Stringverarbeitung verwende ich eher while-Schleifen als>> for-Schleifen. Insbesondere wenn ich nicht abschätzen kann wie lang die>> Zeichenkette denn nun ist, bringt mir die while-Schleife den Vorteil das>> ich mir keine Gedanken um den Datentyp der Zählvariablen machen muss.>> Warum sollten sich for und while da unterscheiden?Frank M. schrieb:> for und while unterscheiden sich lediglich in der Schreibweise.>> for (INIT; CONDITION; REPEAT)> {> ...> }>> lässt sich immer als>> INIT;> while (CONDITION)> {> ...> REPEAT;> }>> schreiben, wobei INIT und REPEAT optional sind. Ein einziger> klitzekleine Unterschied fällt mir ein: CONDITION ist bei der> for-Schleife ebenso optional, bei der while-Schleife jedoch zwingend> anzugeben.
Klar kann man eine for-Schleife immer zu einer while-Schleife
vergewaltigen, bzw. eine while-schleife durch zusätzliche Zeilen zu
einer for-Schleife umfunktionieren.
Um es nochmal richtig zu formulieren: Ich verwende eher das Beispiel mit
der while-Schleife und der Zeigearithmetik als das Beispiel mit der
for-Schleife und der Zählvariablen.
Yalu X. schrieb:> Juergen schrieb:>> MISRA-C:2004 Rule 13.2 (advisory):>> Tests of a value against zero should be made explicit,>> unless the operand is effectively Boolean.>> Da in C die Ergebnisse von Vergleichs- und logischen Operationen den> Datentyp int haben, sollte man nach MISRA also diese Abfrage>>
1
>if(n>=0&&n<=9)
2
>...
3
>
>> durch diese>>
1
>if((((n>=0)!=0)&&((n<=9)!=0))!=0)
2
>...
3
>
4
>
>> ersetzen (natürlich mit Klammern um sämtliche Teilausdrücke).
Ts. ts.
Du bist ja noch nicht fertig!
Auch .... != 0 ist ein Vergleich, der ein int Ergebnis liefert. D.h.
du musst auch hier wieder testen ob das ungleich 0 ergibt. Ad infinitum.
>> ersetzen (natürlich mit Klammern um sämtliche Teilausdrücke).
Das reicht nicht. Das Ergebnis ist wieder ein int. Du musst das
unendlich weiter fortsetzen, bis der Compiler mit einem Stack-Overflow
aussteigt ;-)
Mark Brandis schrieb:>> das ist für MICH leicht lesbar (subjektive Empfindung).>> Aber genau darum geht es NICHT!>> Es geht nicht darum, was für einen einzelnen Programmierer leicht> verständlich ist. Es geht darum, dass alle in einem Projekt bzw. in> einer Firma nach den gleichen Regeln (Codierrichtlinien) programmieren.
Daher hab ich ja auch gesagt, dass ICH keinen Job annehmen würde, in dem
MISRA gefordert wird. Das ist MEINE persönliche Freiheit das zu tun.
Dass natürlich Firmenrichtlinien die persönlichen Einstellungen
selbstverständlich überstimmen, hab ich nicht explizit erwähnt. Sollte
aber klar sein, dass das so ist.
Aber auch Firmenrichtlinien sind ja nicht automtisch ein Garant dafür,
dass ein Code leicht lesbar ist. Es sind Firmenrichtlinien, mehr nicht.
Der selbsternannte Zweck von MISRA ist ja nicht, projektweit gleich
aussehenden Code zu garantieren. (Zumindest ist das nicht der
Hauptzweck)
Auch MISRA schützt mich nicht vor
int i = 8;
char str[5];
str[i] = 'a';
obwohl ich diese Pointer-Index Regel eingehalten habe und somit die
formalen Kriterien erfüllt habe.
Mark Brandis schrieb:> dass alle in einem Projekt bzw. in einer Firma> nach den gleichen Regeln programmieren.
Wenn immer alle das Gleiche machen, kommt immer das Gleiche raus...
;-) duckundwech
Es hilft nichts: wenn einer eine geniale Idee hat, und der andere die
ums Verrecken nicht kapiert, dann helfen auch gleiche Syntax-Regeln
nichts. Oder meinst du, dass die schöne und elegante Tastaturroutine von
PeDa von mehr Programmierern/Kopierern verstanden werden würde, wenn
der Ablauf explizit dastehen würde?
Karl Heinz Buchegger schrieb:> obwohl ich diese Pointer-Index Regel eingehalten habe und somit die> formalen Kriterien erfüllt habe.
Aber analysieren wir doch mal
1
voidlcd_string(constchar*str)
2
{
3
uint8_ti;
4
5
for(i=0;str[i]!='\0';i++)
6
lcd_char(str[i]);
7
}
versus
1
voidlcd_string(constchar*str)
2
{
3
while(*str)
4
lcd_char(*str++);
5
}
In der Array-Version hab ich 2 potentielle Tippfehlerquellen: den
Vergleich und den 2.ten Operanden zum Vergleich.
In der Pointer Version hab ich nur eine: Ich darf den * nicht vergessen.
Zusätzlich hab ich in der Array Version noch das semantische Problem,
dass ich den Datentyp für i nicht verbocken darf, ein Problem welches in
der Pointer Version überhaupt nicht existiert.
So gesehen steht es 3:1 für die Pointerversion und die MISRA Regeln
waren an dieser Stelle kontraproduktiv.
MISRA erzeugt ein Größe, nämlich die Anzahl an Regelverletzungen.
Eine Größe kann man messen und in PowerPoint präsentieren.
Im PowerPoint kann man zeigen, wie die Anzahl an Regelverletzung
abnimmt, was suggeriert, daß die Qualität besser und besser wird.
Genauso wie im Bug-Tracking: trage ich den Fehler als Bug oder
Improvement ein? Die Anzahl an Bugs wird gemessen und sollte sich
kontinuierlich veringern...
M. K. schrieb:>> schreiben, wobei INIT und REPEAT optional sind. Ein einziger>> klitzekleine Unterschied fällt mir ein: CONDITION ist bei der>> for-Schleife ebenso optional, bei der while-Schleife jedoch zwingend>> anzugeben.>> Klar kann man eine for-Schleife immer zu einer while-Schleife> vergewaltigen, bzw. eine while-schleife durch zusätzliche Zeilen zu> einer for-Schleife umfunktionieren.
Umgekehrt: Die zusätzlichen Zeilen gibt's wenn ich aus einer
for-Schleife eine while-Schleife mache.
> Um es nochmal richtig zu formulieren: Ich verwende eher das Beispiel mit> der while-Schleife und der Zeigearithmetik als das Beispiel mit der> for-Schleife und der Zählvariablen.
Der Stichwort bei der Aussage, auf die ich vorher genatwortet hatte, war
"iterieren". Wenn ich eine Art Container habe und darüber iterieren
will, nehme ich eine for-Schleife. Ob das nun ein Array, ein String oder
eine verkettete Liste ist, ist mir dabei egal. Wesentlich ist eher, ob
es bei diesem Aufbau
Frank M. schrieb:> INIT;> while (CONDITION)> {> ...> REPEAT;> }
die Teile INIT und REPEAT gibt. Wenn's zumindest letzeren gibt, dann
läßt mich das schon eher zur for-Schleife tendieren. Dabei muß dann
REPEAT nicht unbedingt ein i++ sein, sondern kann z.b. bei einer
verketteten Liste auch ein p = p->next sein. Hauptsache, es ist die
Anweisung, die beim Iterieren die Aufgabe hat, zum nächsten Element
weiterzuspringen.
Ich finde das leichter lesbar, wenn das alles schön im Schleifenkopf
steht und nicht irgendwo unten im Schleifenkörper oder vor der Schleife
zusammengesucht werden muß. Und ich finde es auch besser lesbar, als
CONDITION und REPEAT miteinander zu vermischen und einen Klumpen draus
zu machen.
Rolf Magnus schrieb:> Wesentlich ist eher, ob> es bei diesem Aufbau>> Frank M. schrieb:>> INIT;>> while (CONDITION)>> {>> ...>> REPEAT;>> }>> die Teile INIT und REPEAT gibt. Wenn's zumindest letzeren gibt, dann> läßt mich das schon eher zur for-Schleife tendieren. Dabei muß dann> REPEAT nicht unbedingt ein i++ sein, sondern kann z.b. bei einer> verketteten Liste auch ein p = p->next sein. Hauptsache, es ist die> Anweisung, die beim Iterieren die Aufgabe hat, zum nächsten Element> weiterzuspringen.
Ok dann könnte ein Kompromiss also wie folgt aussehen:
Lothar Miller schrieb:> Es hilft nichts: wenn einer eine geniale Idee hat, und der andere die> ums Verrecken nicht kapiert, dann helfen auch gleiche Syntax-Regeln> nichts. Oder meinst du, dass die schöne und elegante Tastaturroutine von> PeDa von mehr Programmierern/Kopierern verstanden werden würde, wenn> der Ablauf explizit dastehen würde?
Was glaubst Du, wie viele "geniale Ideen" ich schon in so mancher Leute
Code gesehen habe... erst vor ein paar Tagen z.B. dies hier:
1
for(i=0;i<10;i++)
2
{
3
switch(i)
4
{
5
case0:
6
do_something();
7
break;
8
case1:
9
do_something_else();
10
break;
11
case2:
12
do_yet_something_different();
13
break;
und so weiter...
In 90% der Fälle sind "geniale Ideen" beim Programmieren einfach nur
Bullshit, und zu nichts zu gebrauchen, außer dazu die Wartbarkeit des
Codes zu erschweren. Ausnahmen bestätigen die Regel.
Die Maßeinheit "What the fvck per minute" (nein, das ist kein Spam -
dämliche Foren-Software) bei Code Reviews untermauert dies:
http://www.osnews.com/story/19266/WTFs_m
Wer "geniale Ideen" verwirklichen will, der ist in der Regel (wie
gesagt, 10% sind die Ausnahmen) beim IOCCC gut aufgehoben :-)
http://www.ioccc.org/
Mark Brandis schrieb:> Es geht nicht darum, was für einen einzelnen Programmierer leicht> verständlich ist. Es geht darum, dass alle in einem Projekt bzw. in> einer Firma nach den gleichen Regeln (Codierrichtlinien) programmieren.
Und genau das ist der springende Punkt. Man sollte nur dabei beachten,
das die Varianz zwischen guten und schlechten Programmierern gigantisch
groß ist. Daher stellt sich die Frage: Wie sollen die Regeln aussehen ?
1) Sind die Regeln zu restriktiv, bremse ich meine guten Programmierer
zu stark aus.
2) Sind die Regeln zu lax, bekommen die schlechten jeden Mist durch
die QA.
3) Sind die Regeln schlecht, bremse ich die guten aus, und die
schlechten bekommen dennoch alles durch die QA.
Ich würde MISRA in 3) einordnen. :-)
Gruß Heiko
Mark Brandis schrieb:> Was glaubst Du, wie viele "geniale Ideen" ich schon in so mancher Leute> Code gesehen habe... erst vor ein paar Tagen z.B. dies hier:
Das Problem kenn ich auch. Da wird irgendwas vom Kollegen X kopiert,
ohne zu verstehen was der Happen Code überhaupt macht, mit "eigenen
Ideen" gewürzt und anschliessend mit kleinen Änderungen so oft durch den
build/CI prozess gejagt bis die roten Lämpchen der automatisierten QA
auf allen Ebenen ausgehen.
Ralph schrieb:> Es kann sein das Dein Compiler das richtige macht, aber ein anderer> Compiler eventuell etwas anderes daraus macht.
Klasse Programmiersprache.
Eine Sprachdefinition soll IMHO keine Möglichkeiten für Interpretationen
lassen. Entweder es wird von allen Compilern einheitlich interpretiert
oder von allen einheitlich angemault. Was nützt eine Programmiersprache,
wenn jeder Compilerbauer machen kann, was er will ...
Es wird Zeit für D
Heiko Jakob schrieb:>> 3) Sind die Regeln schlecht, bremse ich die guten aus, und die> schlechten bekommen dennoch alles durch die QA.>> Ich würde MISRA in 3) einordnen. :-)
Wer sich durch MISRA ausbremsen läßt, ist kein guter Programmierer.
Letztlich ist das Kleinkram, und mit der richtigen Einstellung
ist das gar kein Problem.
Jürgen
Yalu X. schrieb:> Juergen schrieb:>> MISRA-C:2004 Rule 13.2 (advisory):>> Tests of a value against zero should be made explicit,>> unless the operand is effectively Boolean.>> Da in C die Ergebnisse von Vergleichs- und logischen Operationen den> Datentyp int haben, sollte man nach MISRA also diese Abfrage> if (n >= 0 && n <= 9)> ...>> durch diese> if ((((n >= 0) != 0) && ((n <= 9) != 0)) != 0)> ...
Deswegen steht da "effectively Boolean".
@ Jürgen
>Deswegen steht da "effectively Boolean".
Ich verstehe Deine Replik nicht.
Ist das ironisch gemeint?
Da es keine boolean Typ gibt, und daher auch keinen solchen Operanden,
muss, der Regel folgend, jeder Vergleich mit Null explizit sein. Macht
man das so, hat man allerdings wieder ein Ergebnis das nicht boolean ist
(weil es das nicht gibt).
Im Umkehrschluss ist der Nachsatz "...unless the operand is effectively
Boolean" völlig sinnlos. Genauso könnte er heissen: "unless the operand
is a strawberry". :-)
Kopfschüttel schrieb:> Es wird Zeit für D
Ach. Es ist Zeit, nicht auf so ein Geschwafel zu hören:
Ralph schrieb:
> Es kann sein das Dein Compiler das richtige macht, aber ein anderer> Compiler eventuell etwas anderes daraus macht.
mfg.
>>>> ersetzen (natürlich mit Klammern um sämtliche Teilausdrücke).>> Das reicht nicht. Das Ergebnis ist wieder ein int. Du musst das> unendlich weiter fortsetzen, bis der Compiler mit einem Stack-Overflow> aussteigt ;-)
Das habe ich gerade mal ausprobiert: Ein simples Stück Quellcode, ein
einfacher Vergleich zwischen 2 ints, aber 100000000 (in Worten: Hundert
Millionen) mal !=0. Naja, die C-Datei ist gute 250MB groß und ein
Prozess namens cc1 meldet nach vielen Minuten Festplattengerödel
(Auslagerungsdatei, ich hab nur 1 GB RAM) ein schnödes "out of memory
allocating irgendwas Bytes". Ein richtiger Absturz ist nicht
hinzukriegen. :-( Spannend wäre es mit >2^32 ob dann irgendein interner
Zähler überläuft, aber das packt meine Kiste nicht.
PS: Hm, irgendwie bemerke ich gerade Spätfolgen, der PC ist unglaublich
lahm. Mal neustarten...
scnr
Juergen schrieb:> Wer sich durch MISRA ausbremsen läßt, ist kein guter Programmierer.
MISRA will gelernt sein, und wer selbst als guter C-Programmierer nur
gelegentlich MISRA konform arbeiten muss, wird die Regeln wohl kaum
verinnerlichen und daher zwar valides C, aber nicht MISRA konformes C
von sich geben, was dann erst mühsam berichtigt werden will. Nach ein
paar Tagen sollte man es aber "verinnerlicht" haben(, um es rechtzeitig
bis zum nächsten Projekt wieder zu vergessen.)
Juergen schrieb:> Deswegen steht da "effectively Boolean".
Da stellt sich jetzt halt die Frage, was "effectively Boolean" genau
bedeutet. Meiner Meinung nach ist fp in der dritten Zeile des
folgenden Codeausschnitts effektiv ein Boolean:
1
FILE*fp;
2
fp=fopen("datei","r");
3
if(fp)
4
// Datei lesen
5
fclose(fp);
6
else
7
// Fehler
Denn:
fp enthält n in Wirklichkeit zwei Informationen:
- den Erfolgsstatus des fopen-Aufrufs (effektiv ein Boolean:
True (!=NULL) -> Erfolg, False (==NULL) -> Fehler)
- im Erfolgsfall den Zeiger auf eine FILE-Struktur
In der If-Bedingung wird nur der boolesche Anteil von fp ausgewertet,
also würde die obige Abfrage perfekt den MISRA-Richtlinien entsprechen.
So weit ich weiß, sieht das MISRA aber anders und erwartet in diesem
Fall einen expliziten Vergleich, also
1
if(fp!=NULL)
Dieser Vergleich mit NULL ist zwar nicht falsch, erscheint mir aber
ähnlich unsinnig wie
1
if((n<10)!=0)
Das Einzige, was man an obigem Code mit dem fopen als unsauber ansehen
könnte, ist die Vermauschelung von zwei Informationen (Erfolgsstatus und
FILE-Zeiger) in einer Variablen eines elementaren Datentyps (Zeiger).
Sauberer wäre ein Struct aus einem Zeiger und einem Valid-Flag. Dies
wiederum wird aber von MISRA (zum Glück) nicht gefordert.
Yalu X. schrieb:> Juergen schrieb:>> Deswegen steht da "effectively Boolean".>> Da stellt sich jetzt halt die Frage, was "effectively Boolean" genau> bedeutet. Meiner Meinung nach ist fp in der dritten Zeile des> folgenden Codeausschnitts effektiv ein Boolean:> FILE *fp;> fp = fopen("datei", "r");> if (fp)
Nein, für "effectively Boolean" nach MISRA gibt es zwei Möglichkeiten:
- Ergebnis einer Vergleichsoperation (==, !=, <, <=, >, >=) oder
logischen Operation (!, &&, ||) ("Boolean by construct")
- Ein durch typedef definierter Boolean-Typ, dessen korrekte Verwendung
z.B. von einem zusätzlichen Tool geprüft werden könnte
("Boolean-by-enforcement")
Ziel ist mit C Bordmitteln einen Boolean-Typ nachzubauen, den C ja
leider nicht hat.
Juergen schrieb:> - Ergebnis einer Vergleichsoperation (==, !=, <, <=, >, >=) oder> logischen Operation (!, &&, ||) ("Boolean by construct")
Na also.
Damit kann man Vergleiche mit 0/NULL also MISRA-konform umformulieren:
Statt
if (fp == NULL)
ist also
if (!fp)
zulässig.
Rufus Τ. Firefly schrieb:> Damit kann man Vergleiche mit 0/NULL also MISRA-konform umformulieren:>> Statt>> if (fp == NULL)>> ist also>> if (!fp)>> zulässig.
Netter Versuch:
Rule 12.6 (advisory):
The operands of logical operators (&&, || and !) should be
effectively Boolean. Expressions that are effectively Boolean should
not be used as operands to operators other than (&&, || and !).
Und, findest Du auch noch eine Definition, was "effectively boolean" nun
genau sein mag?
Nein, Interpretationen aus der Anwendung von Ausdrücken, die
"effectively boolean" sind, sind hier nicht zulässig, denn das wäre eine
rekursive Definition.
Rufus Τ. Firefly schrieb:> Und, findest Du auch noch eine Definition, was "effectively boolean" nun> genau sein mag?
Der erste Teil der Definition:
> Ergebnis einer Vergleichsoperation (==, !=, <, <=, >, >=)
Ein Vergleich darf (bzw. muss?) natürlich andere Eingangstypen als
"effectively boolean" haben. Die logischen Operatoren (!, &&, ||) müssen
dagegen auf "effectively boolean" durchgeführt werden. Also so, wie es
der "gesunde Menschenverstand" abseits von C auch erwarten würde.
Rufus Τ. Firefly schrieb:> Und, findest Du auch noch eine Definition, was "effectively boolean" nun> genau sein mag?
Genau deswegen braucht es Standards mit 1000 Seiten: Weil es zu viele
Leute gibt, die Querulanten sind und den ganzen Tag damit verschwenden,
allerkleinste Definitionslücken zu suchen obwohl es jedem längst klar
ist, was gemeint ist.
Ich musste erst kürzlich so einen feuern. Ein begnadeter Entwickler,
aber leider nur Solo einsetzbar, weil er nie bereit war sich an die
Regeln zu halten die nunmal dafür da sind Ergebnisse zu produzieren, die
auch für die Durchschnittsleute im Team verwendbar sind. Da half auch
wochenlanges Erklären und gutes Zureden nicht. Und mit einem Genie
alleine kann man leider kein Projekt durchziehen.
Marwin schrieb:> Weil es zu viele> Leute gibt, die Querulanten sind und den ganzen Tag damit verschwenden,> allerkleinste Definitionslücken zu suchen obwohl es jedem längst klar> ist, was gemeint ist.
Wer Standards so interpretiert, daß er Interpretationslücken durch "was
gemeint ist" ersetzt, sollte sehr vorsichtig sein, wen er als
"Querulanten" bezeichnet.
Troll doch einfach woanders.
Marwin schrieb:>> Genau deswegen braucht es Standards mit 1000 Seiten:
Wobei MISRA-C:2004 mit allem drum und dran nur 119 Seiten hat.
Man braucht aber noch zusätzlich Regeln zum Layout,
und an einzelnen Stellen ist MISRA auch Wischiwaschi
(z.B. wieviele Klammern man in Ausdrücken setzen soll).
> die Querulanten sind und den ganzen Tag damit verschwenden,> allerkleinste Definitionslücken zu suchen obwohl es jedem längst> klar ist, was gemeint ist.
Hmm.
Diese 'Querulanten' nennt man in anderen Bereichen zum Beispiel
'oberster Gerichtshof'.
Denn genau das kommt dabei raus, wenn man keine ordentlichen
Definitionen hat: unser Rechtssystem, bei dem es drauf ankommt welchen
Richter du erwischt und wie der 'die Regeln' auslegt.
Das mag bei menschlichen Richtern noch ok sein, aber bei einer
Programmiersprache, die von einer Maschine übersetzt wird, ist es das
nicht. Da muss jedes 'allen ist klar wie es gemeint ist' aussen vor
gelassen werden so gut es nur irgendwie geht. In C ist zwar vieles offen
gelassen aber entgegen landläufiger Meinung (siehe zb weiter oben), sind
die meisten Sachen nicht verhandelbar. Operator Precedence ist nicht
Glückssache, sondern exakt geregelt, Ralph. Und wer die nicht
vollständig auswendig weiß, der schlägt sei entweder nach oder verwendet
Klammern nach eigenem Ermessen. MISRA ist kein Ersatz dafür, sein
Werkzeug zu kennen. Denn dort liegt doch oft das eigentliche Problem.
> Ein begnadeter Entwickler, aber leider nur Solo einsetzbar, weil> er nie bereit war sich an die Regeln zu halten
Das ist aber wieder was anderes.
Wenn die Firma die Regeln vorgibt, dann tut sie das.
Aber das bedeutet nicht per se, dass die Regeln sinnvoll sind.
Karl Heinz Buchegger schrieb:> Wenn die Firma die Regeln vorgibt, dann tut sie das.> Aber das bedeutet nicht per se, dass die Regeln sinnvoll sind.
Oder was der wahre Hintergrund solcher Regeln ist.
Eine perfekt verständlicher und nachvollziehbarer Code erlaubt es ja
auch, die Bearbeiter beliebig auszutauschen bzw. die ganze Entwicklung
nach Indien outzusourcen.
Insofern hab ich das Gefühl, daß die Ablehnung solcher Regeln auch etwas
mit Selbsterhalt (bzw. Arbeitsplatzerhalt) zu tun hat.
Karl Heinz Buchegger schrieb:> Hmm.> Diese 'Querulanten' nennt man in anderen Bereichen zum Beispiel> 'oberster Gerichtshof'.> Denn genau das kommt dabei raus, wenn man keine ordentlichen> Definitionen hat: unser Rechtssystem, bei dem es drauf ankommt welchen> Richter du erwischt und wie der 'die Regeln' auslegt.
Da hast du jetzt was Grundlegendes an meiner Aussage nicht verstanden.
Denn dein Beispiel ist super: Nur sind die Querulanten die Leute, die
die Luecken in den Gesetzen suchen und ausnutzen und sich nachher a)
wundern, dass ein Gericht es wagt die Luecke nicht zu akzeptieren, weil
die Intention des Gesetzes voellig klar war und er dagegen verstossen
hat und es b) immer mehr Gesetze gibt, um diese Luecken zu schliessen.
> Das mag bei menschlichen Richtern noch ok sein, aber bei einer> Programmiersprache, die von einer Maschine übersetzt wird, ist es das> nicht. Da muss jedes 'allen ist klar wie es gemeint ist' aussen vor> gelassen werden so gut es nur irgendwie geht.
Dann praesentiere uns doch mal deine lueckenlosen Coding-Styleguides,
die frei von jedem Interpretationsspielraum sind.
> MISRA ist kein Ersatz dafür, sein> Werkzeug zu kennen. Denn dort liegt doch oft das eigentliche Problem.
Was du zuhause machst, ist deine Sache. Aber wer fuer Andere arbeitet,
muss seinen Fokus auf Problemloesungen legen und nicht auf
Selbstverwirklichung. Und dabei geht es nunmal darum, mit den real
existierenden Moeglichkeiten reale Loesungen zu schaffen und nicht sich
in einen Elfenbeinturm zu setzen und das Projekt zu sabotieren.
Marwin schrieb:> Was du zuhause machst, ist deine Sache. Aber wer fuer Andere arbeitet,> muss seinen Fokus auf Problemloesungen legen und nicht auf> Selbstverwirklichung. Und dabei geht es nunmal darum, mit den real> existierenden Moeglichkeiten reale Loesungen zu schaffen und nicht sich> in einen Elfenbeinturm zu setzen und das Projekt zu sabotieren.
Und was ist wenn das Problem nicht mit MISRA regeln lösbar ist? Wird
dann dem Kunden gesagt das es nicht umsetzbar ist?
Zur optimierung muss man manchmal code schreiben der nicht "schön"
aussieht aber notwendig ist.
Klar könnte man denn schnellere CPUs verwenden, aber nur damit die
Regeln eingehalten werden ist nicht gerade sinnvoll.
Peter II schrieb:>> Und was ist wenn das Problem nicht mit MISRA regeln lösbar ist? Wird> dann dem Kunden gesagt das es nicht umsetzbar ist?
Nein, du darfst auch in Einzelfällen gegen Regeln verstoßen,
wenn das nötig ist, mußt das aber dokumentieren, Erlaubnis
von höherer Stelle einholen etc.
Näheres regelt dein Qualitäter.
Peter II schrieb:> Hier mal ein beispiel von solchen code
Und das soll funktionieren? Start 'do/while' innerhalb von 'case 0' und
das Ende vor der 'switch-Klammer'? Das werd' ich nie begreifen...
Ralf G. schrieb:> nd das soll funktionieren?
warum nicht, die case sind auch nur spunglabels. Das ganze sieht zwar
ungewöhnlich aus aber wenn einen klar ist das auch Schleifen immer nur
Sprünge sind dann ist es eigentlich klar.
Marwin schrieb:>> MISRA ist kein Ersatz dafür, sein Werkzeug zu kennen. Denn dort liegt>> doch oft das eigentliche Problem.>> Was du zuhause machst, ist deine Sache. Aber wer fuer Andere arbeitet,> muss seinen Fokus auf Problemloesungen legen und nicht auf> Selbstverwirklichung.
Es geht nicht um Selbstverwirklichung, sondern darum, daß jeder, der
professionell mit Werkzeugen arbeitet, den Umgang damit zu beherrschen
hat. Und der Compiler/die Programmiersprache ist so ein Werkzeug.
Irgendwelche Regeln wie MISRA können das nicht ersetzen.
Wenn jemand mit einem Hammer nicht umgehen kann, hältst du ihn nicht
davon ab, sich auf den Finger zu hauen, indem du ihm die Regel gibst,
den Hammer nicht falsch rum zu halten.
Rolf Magnus schrieb:>> Es geht nicht um Selbstverwirklichung, sondern darum, daß jeder, der> professionell mit Werkzeugen arbeitet, den Umgang damit zu beherrschen> hat. Und der Compiler/die Programmiersprache ist so ein Werkzeug.> Irgendwelche Regeln wie MISRA können das nicht ersetzen.
Sollen sie auch nicht.
MISRA ist nur ein Werkzeug, um die gefährlichen und schwer
verständlichen Teile von C einigermaßen zuverlässig zu umschiffen.
Als Beispiel mag die "Das hier sollte fehlerfrei sein"-Schleife weiter
oben dienen.
Ich nochmal, ausnahmsweise.
@Peter
Hat das dann noch eine Bedeutung, dass das 'do {' hinter dem 'case 0:'
steht? Oder soll's nur ein bisschen gruseliger/technischer/... aussehen?
>Und das soll funktionieren?
Ja. Aber nur in C.
In anderen Programmiersprachen klappt das in-einander-schachteln von
CASE und WHILE nicht. Da meckert schon der Compiler rum. Aber hier, wie
schon gesagt, wird das alles nur als Sprungmarken betrachtet. Und while
ist ja auch nur ein (bedingter) Sprung
Ralf G. schrieb:> @Peter> Hat das dann noch eine Bedeutung, dass das 'do {' hinter dem 'case 0:'> steht? Oder soll's nur ein bisschen gruseliger/technischer/... aussehen?
meinst du weil es auf der gleiche zeile steht oder weil es dort
überhaupt steht?
Ja das ganze hat sinn, dieser sinn steht auch im Text. Es spart das
ständige vergleich ob schon das ende ereicht ist.
Peter II schrieb:> meinst du weil es auf der gleiche zeile steht oder weil es dort> überhaupt steht?
Nee, ich hätte es ;-) (nachdem ich begriffen habe, worum es geht) vor
das 'case 0:' geschrieben. Nur, damit's schöner aussieht. Ob das 'case
0:' jetzt vor oder in der Klammer angesprungen wird, ist doch egal. Oder
habe ich da was übersehen??
Bronco schrieb:> Oder was der wahre Hintergrund solcher Regeln ist.> Eine perfekt verständlicher und nachvollziehbarer Code erlaubt es ja> auch, die Bearbeiter beliebig auszutauschen bzw. die ganze Entwicklung> nach Indien outzusourcen.
Nein, das ist nicht der Hintergrund.
Der Hintergrund ist der, dass man professionelle Software haben will,
die einem von ihrer Qualität her nicht andauernd um die Ohren fliegt. In
vielen Bereichen braucht man einfach sauberen Code: Medizintechnik,
Luft- und Raumfahrt, Schienenverkehrstechnik - um ein paar Beispiele zu
nennen.
Da kommt man mit dem Ansatz "Ich programmiere aber so wie ich es für
richtig halte, mir doch egal wenn ich meinen Kollegen damit das Leben
schwer mache" nicht weit.
> Insofern hab ich das Gefühl, daß die Ablehnung solcher Regeln auch etwas> mit Selbsterhalt (bzw. Arbeitsplatzerhalt) zu tun hat.
Das ist meiner Erfahrung nach in vielen Fällen nur eine Ausrede.
Meistens kommt sie von den Leuten, die keine Lust haben sich
fortzubilden. Sehe ich regelmäßig in unserer Abteilung: Die Leute, die
miteinander Bücher über Softwareentwicklung lesen und besprechen, haben
in aller Regel kein Problem damit, sich an Codierrichtlinien zu halten.
Die anderen sind diejenigen, die gerne mal "Sonderlösungen" stricken,
welche die Wartbarkeit des Codes deutlich verschlechtern.
Mark Brandis schrieb:> Der Hintergrund ist der, dass man professionelle Software haben will,> die einem von ihrer Qualität her nicht andauernd um die Ohren fliegt. In> vielen Bereichen braucht man einfach sauberen Code: Medizintechnik,> Luft- und Raumfahrt, Schienenverkehrstechnik - um ein paar Beispiele zu> nennen.
das ist doch vollkommen klar. Braucht man nicht drüber zu diskutieren.
Genauso wenig wie darüber:
> Da kommt man mit dem Ansatz "Ich programmiere aber so wie ich es für> richtig halte, mir doch egal wenn ich meinen Kollegen damit das Leben> schwer mache" nicht weit.
Aber "if(fp == NULL)" statt "if(!fp)" ist eine Vorschrift um der
Vorschrift Willen. Denn das ist C und wird von jedem C-Programmierer
verstanden. Und eine Lusche verbessert man damit auch nicht.
mfg.