schon? (warning: large integer implicitly truncated to unsigned type)
Mathematisch gesehen läuft es doch wohl aufs gleiche raus... ich meine
die Variable a hat danach so oder so den gleichen Wert, und in beiden
Fällen wollte man mehr in sie reinstecken als reinpasst ;-)
Ist das nur beim gcc so oder ist das generell ANSI-C Standard?
>> schon? (warning: large integer implicitly truncated to unsigned type)>> Mathematisch gesehen läuft es doch wohl aufs gleiche raus...
Ja. Für dich schon.
Im Prinzip könnte der Compiler im ersten Beispiel das genauso
detektieren, wenn er sich den Datenfluss ansieht und verfolgt, welche
Variable wann welchen Wert hat. Nur wind wohl die Compilerbauer davon
ausgegangen, das das so keiner machen wird. Für den Compiler steht da
erst mal einfach nur
a = b;
b ist eine Variable und damit wird erst mal nichts über den Inhalt der
Variablen angenommen. b könnte ja durchaus einen Inhalt haben, der
problemlos in a hineinpasst und dann wäre diese Warnung unangebracht.
Ganz im Gegenteil: In dein meisten Programmen würde es dann vor solchen
Warnungen nur noch so wimmeln. C legt (anders als andere Sprachen) da
einfach mehr Verantwortung auf den Programmierer. Oder anders gesagt:
Wenn du eine Tante brauchst, die mit dir Lulu geht, dann bist du bei C
an der falschen Sprache.
> Ist das nur beim gcc so oder ist das generell ANSI-C Standard?
Der Sprachstandard verlangt von einem Compiler überhaupt keine
Warnungen. Warnungen sind Good-will Dinge, die ein Compilerbauer von
sich aus einbaut.
Wunderer schrieb:> Wie kommt es eigentlich, dass das hier:> ...> keine Warnung ergibt, aber das hier:> ...> schon? (warning: large integer implicitly truncated to unsigned type)
Wie sieht deine Kommandozeile beim Kompilieren aus? Hast du alle
Warnungen eingeschaltet (-Wall oder -Wextra) oder nicht?
Interessant ist für dich auch -Wconversion und -Wno-sign-conversion
http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
Bei
unsigned char a;
unsigned int b = 0x12345678;
a = b;
sollte es im Idealfall letztendlich zwei Warnungen geben, wenn int
16-Bit groß ist.
Dafür: unsigned int b = 0x12345678;
und dafür: a = b;
Karl heinz Buchegger schrieb:>> Ist das nur beim gcc so oder ist das generell ANSI-C Standard?>> Der Sprachstandard verlangt von einem Compiler überhaupt keine> Warnungen. Warnungen sind Good-will Dinge, die ein Compilerbauer von> sich aus einbaut.
Naja, es gibt durchaus Stellen, an denen der Compiler verpflichtet ist,
eine "diagnostic message" auszugeben.
Stefan B. schrieb:> Wie sieht deine Kommandozeile beim Kompilieren aus? Hast du alle> Warnungen eingeschaltet (-Wall oder -Wextra) oder nicht?
-Wall ist aktiviert, damit gibt es genau die eine Warnung die ich oben
"copy and pasted" habe. Die gcc Version hierbei ist:
gcc (GCC) 3.4.5 (mingw-vista special r3)
"int" ist bei mir übrigens 32 Bit groß.
Ach ja und die Erklärung von Karl heinz Buchegger finde ich nicht
wirklich überzeugend. Gerade wenn man sowas hier macht:
1
intSendedatum=0x12345678;
2
unsignedcharSendepuffer[sizeof(int)];
3
4
Sendepuffer[0]=Sendedatum>>0;
5
Sendepuffer[1]=Sendedatum>>8;
6
Sendepuffer[2]=Sendedatum>>16;
7
Sendepuffer[3]=Sendedatum>>24;
finde ich es befremdlich dass es hierbei keinerlei Warnungen gibt. Das
ist so wie wenn ich zu viel Wasser in einen Eimer einfülle und die
Laufzeitumgebung mich nicht warnt, dass es dann einen Verlust an Wasser
gibt. (ups :)
Wunderer schrieb:> gcc (GCC) 3.4.5 (mingw-vista special r3)> "int" ist bei mir übrigens 32 Bit groß.
Ah, klar dann.
> finde ich es befremdlich dass es hierbei keinerlei Warnungen gibt.http://www.umfi.de/prospr.htm
Wunderer schrieb:> Das ist so wie wenn ich zu viel Wasser in einen Eimer einfülle und die> Laufzeitumgebung mich nicht warnt, dass es dann einen Verlust an Wasser> gibt. (ups :)
Dir geht es aber nicht um die Laufzeitumgebung, sondern um den Compiler.
Du erwartest also vom Hersteller des Wasserhahns, daß er dich vor dem
Befüllen des Eimers darüber informiert, daß er möglicherweise überlaufen
könnte, wenn du den Wasserhahn nicht rechtzeitig zudrehst.
Die Mechanismen im Compiler sind aber meines Erachtens schon da, wie
meine im ersten Post gezeigte Warnung zu beweisen scheint. Warum man
diese Möglichkeit dann nicht konsequent nutzt: Das ist es, was ich nicht
verstehe.
Wunderer schrieb:> Die Mechanismen im Compiler sind aber meines Erachtens schon da, wie> meine im ersten Post gezeigte Warnung zu beweisen scheint.
Dort wird direkt eine Konstante einer Variablen zugewiesen, die für den
Wert zu klein ist. Das kann eigentlich nur ein Fehler sein, denn warum
sollte jemand da einen fixen Wert hinschreiben, der gar nicht in die
Zielvariable paßt?
Anders ist das, wenn man eine Variable einer anderen zuweist. Da kann
das Abschneiden gewollt sein oder es kann schon vorher sichergestellt
worden sein, daß der Wert paßt.
warning C4244: '=' : conversion from 'unsigned long' to 'unsigned char', possible loss of data
Der zweite Fall ist gleich 2 Warnungen wert:
1
warning C4305: '=' : truncation from 'const int' to 'unsigned char'
2
warning C4309: '=' : truncation of constant value
> Beitrag #1877308 wurde gelöscht.> Ausser den trivalsten Programmen, wird es dann nur> so von Warnungen wimmeln.
Ich nehme Visual C++ als Entwicklungsplattform und Editor. Dann drücke
ich zwischendurch schon mal auf den Compilieren-Button. Und dann hat da
nichts zu wimmeln... :-o
Wunderer schrieb:> Warum man> diese Möglichkeit dann nicht konsequent nutzt: Das ist es, was ich nicht> verstehe.
Weil die Fehlermeldung extrem nervig wäre! Beispiele:
1
int32_ta;
2
int32_tb;
3
int8_tdiff;
4
5
/* Sinnvoll, wenn der Programmierer weiß, dass die Differenz nie
Rolf Magnus schrieb:> Anders ist das, wenn man eine Variable einer anderen zuweist. Da kann> das Abschneiden gewollt sein
Ich dachte für sowas (unter anderem) gibt es casts :-O
Wunderer schrieb:> Rolf Magnus schrieb:>> Anders ist das, wenn man eine Variable einer anderen zuweist. Da kann>> das Abschneiden gewollt sein>> Ich dachte für sowas (unter anderem) gibt es casts :-O
Ja.
Aber gerade in der µC Programmierung wimmelt es dann nur so von Casts.
Casts sind aber Waffen! Wenn es nicht sein muss, dann castet man nicht
freiwillig.
Ausserdem: Was bringts dir, wenn du dann ganz einfach überall einen Cast
hinmachst? Dadurch ist nichts gewonnen, die Dinge können aber (bei
Änderungen) noch viel schlimmer werden - durch den Cast!
Und wer in seinem Programm nicht soweit Ordnung halten kann, dass er
beim automatischen Runtercasten auf einen kleineren Datentyp nicht auf
die Nase fällt, ...... der hat dann ganz schnell noch ganz andere, viel
schwerwiegendere Probleme.
Wunderer schrieb:> Ich hatte zuerst gedacht, das Gecaste und Ver-UND-ere hätte einen Sinn> ;-)
Solange sicher gestellt ist, dass der Datentyp von Sendepuffer immer
unsigned char (bzw UINT8) ist, kannst du dir das sparen.
Wunderer schrieb:> Wie kommt es eigentlich, dass das hier:>> unsigned char a;> unsigned int b = 0x12345678;> a = b;>> keine Warnung ergibt, aber das hier:>> unsigned char a;> a = 0x12345678;>> schon?
Weil das eine Äpfel sind und das andere Birnen. Um für Birnen zu warnen
fehlt das -Wconversion.
Johann L. schrieb:> Weil das eine Äpfel sind und das andere Birnen. Um für Birnen zu warnen> fehlt das -Wconversion.
Macht bei mir genau gar keinen Unterschied:
D:\Dateien\C\32in8warning>gcc -Wconversion main.c -o 32in8bit.exe
main.c: In function `test2':
main.c:14: warning: large integer implicitly truncated to unsigned type
D:\Dateien\C\32in8warning>gcc -Wall main.c -o 32in8bit.exe
main.c: In function `test2':
main.c:14: warning: large integer implicitly truncated to unsigned type
Wunderer schrieb:> Rolf Magnus schrieb:>> Anders ist das, wenn man eine Variable einer anderen zuweist. Da kann>> das Abschneiden gewollt sein>> Ich dachte für sowas (unter anderem) gibt es casts :-O
Laut ISO-C ist kein Cast nötig, wenn man von einem größeren Typ in einen
kleineren kopiert. Das gilt im Übrigen sowohl für Variablen, als auch
für Konstanten, denn sonst müßte das da auch schon eine Warnung geben:
1
charc=1;
Schließlich ist 1 vom Typ int, der (auf den meisten Plattformen) größer
ist als char, und damit wäre es wie in diesem Fall, wo er deiner Meinung
nach eine Warnung bringen sollte:
1
inti=1;
2
charc=i;
In solchen Fällen warnt gcc deshalb nicht. Erst wenn man eine Konstante
zuweist, die tatsächlich einen Wert hat, der außerhalb dessen liegt, was
der Zieldatentyp aufnehmen kann, gibt es eine Warnung.
Einerseits muß der Compiler ja den Wert kennen, was eine Konstante
voraussetzt, zweitens kann er bei dieser davon ausgehen, daß es keine
Absicht war.
Wunderer schrieb:> Johann L. schrieb:>> Weil das eine Äpfel sind und das andere Birnen. Um für Birnen zu warnen>> fehlt das -Wconversion.>> Macht bei mir genau gar keinen Unterschied:
Liegt vielleicht an der GCC-Version. Meine horcht auf 4.5.1