Warnungsfreien code schreiben....
-
InterfaceBasis::ZumUeberschreiben(int, int, int) { return NOT_SUPPORTED; }
-
Vielen dank für die Tips.
Also auf das mit der for endlosschleife hätte man kommen können, nagut;)
Die Idee mit den Parametern nur mit Typen finde ich auch klasse das dürfte auch helfen.
Bei der Wertzuweisung sehe ich aber sein wirkliches Problem immer noch nicht. Er beschwert sich das er den Wert verkürzt aber das ist überhaupt nicht das was ich von ihm will (und ich hoffe auch nicht das was er tut, sonst hab ich an der stelle wirklich mehr probleme als eine einfache Warnung). Ich will einfach nur das er die char variable für die Zuweisung wie ein Byte ansieht vollkommen unabhängig davon ob das ding nun im späteren verlauf als vorzeichenbehaftet oder nicht angesehen wird, sprich ein
memcpy(&c, "\xE8", 1);
und das tut er ja soweit ich weiß auch. dementsprechend verkürzt er ja keinen wert sondern deren interpretation ändert sich von 232 in -24. Das er warnt ist ja auch vollkommen okay, aber warum hat er trotz eines casts immer noch ein problem? Wenn ich sowas schreibe gibts keine Warnung:
unsigned long l;
char c = (char)l;und da kann es wirklich gut passieren das informationen verloren gehen und sich nicht nur deren interpretation ändert.
-
template schrieb:
Wenn ich sowas schreibe gibts keine Warnung:
Weil der Compiler davon ausgeht, dass wenn du schon einen cast verwendest, du auch genau weißt, was du tust.
-
char c = '\xE8';0xE8 ist vom Typ int. Wenn Du einen int einem char zuweist, kann das gefährlich sein.
-
template schrieb:
Also auf das mit der for endlosschleife hätte man kommen können, nagut;)
Nene. Es geht hier nicht darum, eine Technik zu finden, um die Compiler-Warnung auszuhebeln. while( true ) mit break ist manchmal schlechter Stil und lässt sich oft übersichtlicher mit einer anständigen while-Bedingung formulieren. Daher warnt der Compiler dich. Wenn du allerdings der Meinung bist, dass dein Stil in Ordnung geht, dann stell doch diese spezielle Warnung einfach aus. Mit for( ;; ) hast du nichts besser gemacht.
-
Ich finde es komisch das du eine do...while Schleife für das erste Beispiel genommen hast. Macht für mich den Eindruck als du du den Sinn davon nicht verstanden hast.
-
Ja gut, aber warum glaubt mir der compiler dann nicht das ich mit dem hex zu char cast weis was ich tue?
Ja einen int in einen char zu konvertieren ist möglicherweise verlustbehaftet aber gerade in diesem fall weiß der compiler ja sicher das der Platz ausreicht, weil die Konstante ohne bitverluste in einem Byte unterzubringen ist.
Naja eigentlich geht es mit unter schon darum den Code warnungsentsprechend umzustellen. Gut ich gebe zu mit einer komplett leeren for schleife ist das ganze ein bischen sauberer als mit dem Risiko das der compiler aus dem while (TRUE) ein
mov ax, 1
jnz schleifenanfangmacht, aber so im großen und ganzen 100%tig hübsch ist die for( ;; ) ja nun rein leserlich auch nicht wirklich.
Und mir ist durchaus bewusst, dass dass nicht der normale Weg ist eine schleife mit einem break zu beenden aber es geht eben manchmal einfacher:
do { /* tue was */ if (/* tue was anderes */ == 0) break; /* tue noch was anderes */ } while (TRUE); // anstatt int stayinloop = 1; do { /* tue was */ if (/* tue was anderes */ == 0) stayinloop = 0; if (stayinloop) { /* tue noch was anderes */ } } while (stayinloop);
-
template schrieb:
// Problem InterfaceBasis::ZumUeberschreiben(int param1, int param2, int param3) { return NOT_SUPPORTED; }Soweit ich weiss, muß man in C++ keinen Parameternamen angeben. Der GCC meckert hier auch, aber nicht bei folgendem Code:
InterfaceBasis::ZumUeberschreiben(int, int, int) { return NOT_SUPPORTED; }Es ist halt nur gefährlich manchmal einen Parameternamen wegzunehmen, weil die Warnung doch ein Anzeichen für einen Bug sein kann. Aber insgesamt halte ich das Verhalten für sinnvoll.
-
tntnet schrieb:
char c = '\0xE8';0xE8 ist vom Typ int. Wenn Du einen int einem char zuweist, kann das gefährlich sein.
Das ist nicht richtig. Character-Literale sind in C++ vom Typ char. In C war das anders.
Und char c = 0xE8 ist sehr wohl verlustbehaftet, wenn char signed ist, denn 0xE8 ist größer als 0x7F, der größte signed char. Der Standard verspricht keine Bitdarstellung im 2er-Komplement, auch wenn das üblich ist. Eine Darstellung mit Vorzeichen-Bit wäre genauso möglich - wo dann 0xE8 nicht mehr so einfach sinnvoll umgewandelt werden könnte.
char c = '\0xE8';sollte AFAIK aber korrekt sein.
-
template schrieb:
Und mir ist durchaus bewusst, dass dass nicht der normale Weg ist eine schleife mit einem break zu beenden aber es geht eben manchmal einfacher:
Geht doch nicht darum, sondern um den Fall, das deine Condition niemals eintrifft, die den Break schmeisst.
Ich hab mir z.B: deshalb angewöhnt bei "endlosschleifen" immer das Abbruchkriterium auf einen Schliess-Request zu setzen. Selbst wenn sich die Applikation aufhängt, kann ich sie dann jederzeit noch schliessen und die Kontrolle behalten. Gegenteiliges ist der Fall, wenn die Applikation nicht mehr reagiert, sich nicht beenden lässt und dann per TM aus dem Speicher entfernt wird.
Das Selbe gilt übrigens auch für irgendwelche WaitFor*Objects-Aurufe in der WinAPI, etc. Hier habe ich mir ebenfalls angewöhnt, nur noch auf multiple Obejkte zu warten, wobei eines davon immer der Close-Event war, der bei einem Close-Request ausgelöst wurde.