Unsigned i=0 ???



  • Hi,
    ich weiß ja das unsigned eine Variable beschreibt die nicht negativiert werden kann,
    so wie z.B.

    unsigned int i=-1; //Geht nicht würde einen Underflow geben
    

    Was soll es bedeuten wenn keine nähere Varibalebeschreibung da ist, so wie z.B.

    unsigned i=0; //Was für ein Variablentyp ist i?
    


  • wenn kein typ angegeben ist, dann immer "int"



  • Ach so, danke!



  • GuardianOfLife schrieb:

    unsigned int i=-1; //Geht nicht würde einen Underflow geben
    

    Bei unsigned Datentypen gibt es weder under- noch overflows(Moduloarithmetik).
    Eine -1 ist Hexadezimal FFFFFFFF (32Bit Maschine).
    unsigned int i=-1; bewirkt also eine Zuweisung des obigen Bitmusters, was als UINT_MAX interpretiert wird.



  • modulo arithmetik0r schrieb:

    GuardianOfLife schrieb:

    unsigned int i=-1; //Geht nicht würde einen Underflow geben
    

    Bei unsigned Datentypen gibt es weder under- noch overflows(Moduloarithmetik).
    Eine -1 ist Hexadezimal FFFFFFFF (32Bit Maschine).
    unsigned int i=-1; bewirkt also eine Zuweisung des obigen Bitmusters, was als UINT_MAX interpretiert wird.

    Und ich dachte, die unsigned-Datentypen schützen davor, dass man versehentlich negative Werte zuweist.



  • Roger Wilco schrieb:

    Und ich dachte, die unsigned-Datentypen schützen davor, dass man versehentlich negative Werte zuweist.

    Der Wert ffffffff ist ja derselbe, ob du ihn nun signed oder unsigned interpretierst. Würdest du hexadezimal zuweisen, käme dir der Gedanke wahrscheinlich gar nicht. 😉



  • Der Compiler könnte aber das Vorzeichen auswerten und warnen anstatt einfach nur in hex zuzuweisen.

    Das heißt, man sollte nicht-unsigned datentypen verwenden, wenn man den Fehler, dass ein Benutzer eine negative Zahl verwendet hat abfangen möchte?

    void foo(unsigned i){ // Negative Zahlen werden kommentarlos akzeptiert.
    
       // Hat der Benutzer aus Versehen eine negative Zahl eingegenen? Ich weiß es nicht.... ;(
    }
    void foo(long i){
        if(i < 0){ // Fehler! }; // Kann überprüft werden
    }
    


  • Roger Wilco schrieb:

    Der Compiler könnte aber das Vorzeichen auswerten und warnen anstatt einfach nur in hex zuzuweisen.

    Tut er ja auch. Er gibt immer eine Warnung aus, wenn ein signed Datentyp einem unsinged Datentyp zugewiesen wird. Aber da es nur eine Warnung ist muss er weitermachen und irgendwas tun - z.B. den entsprechenden Hex-Wert zuweisen.



  • pumuckl schrieb:

    Roger Wilco schrieb:

    Der Compiler könnte aber das Vorzeichen auswerten und warnen anstatt einfach nur in hex zuzuweisen.

    Tut er ja auch. Er gibt immer eine Warnung aus, wenn ein signed Datentyp einem unsinged Datentyp zugewiesen wird. Aber da es nur eine Warnung ist muss er weitermachen und irgendwas tun - z.B. den entsprechenden Hex-Wert zuweisen.

    Bei mir (VC6.0) nicht (Warnstufe 4):

    #include <iostream>
    
    void foo(unsigned int i){
        std::cout << "foo: " << i << std::endl;
    }
    
    int main(int argc, char* argv[])
    {	
        unsigned int i = -1;
        std::cout << "main: " << i << std::endl;
        foo(-5);
        return 0;
    }
    

    VC6.0: schrieb:

    Kompilierung läuft...
    Test.cpp
    Linker-Vorgang läuft...

    Test.exe - 0 Fehler, 0 Warnung(en)

    Ausgabe: schrieb:

    main: 4294967295
    foo: 4294967291



  • pumuckl schrieb:

    Aber da es nur eine Warnung ist muss er weitermachen und irgendwas tun - z.B. den entsprechenden Hex-Wert zuweisen.

    Doch, das Verhalten ist definiert, siehe 4.7§2. (Edit: Hier stand vorher Unsinn.)

    @Roger Wilco: Warnungen sind immer optional. Im Standard steht nirgends was von Warnungen. Ein Compiler dürfte sogar vor einem konformen Programm warnen 🙂



  • Bashar schrieb:

    Um genau zu sein, muss der Wert übernommen werden, wenn er repräsentiert werden kann (also wenn er nichtnegativ ist und der Zieltyp nicht zu klein ist) und ansonsten implementation-defined.

    Sprich, der C++ Standard schreibt nicht vor, was bei einer Zuweisung eines negativen Wertes passiert?



  • Hm. Sorry, bin im Absatz verrutscht 😞 , es ist doch definiert:

    4.7§2: "If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2^n where n is the number of bits used to represent the unsigned type)."



  • Verstehe ich nicht ganz.

    Wird einer vorzeichenloser Ganzzahl eine Vorzeichen-behafteten Ganzzahl zugewiesen, so ist das Ergebnis die kleinste vorzeichenlose Ganzzahl, die der Quellzahl entspricht?



  • Da steht kongruent modulo 2^n. Mal ein Beispiel. Du hast die Zahl -200 und möchtest sie in unsigned char (mit CHAR_BIT=8) speichern. 2^8 ist 256. Genau die Zahlen -200 + k*256 (k ganze Zahl) sind also (modulo 256) kongruent zu -200, nur die nichtnegativen Zahlen sind interessant, also 56, 312, 568, 824, ..., und davon die kleinste ist 56.
    Man hätte das "least" weglassen können, weil von diesen Zahlen sowieso immer nur eine im Zieltyp darstellbar ist.



  • Roger Wilco schrieb:

    pumuckl schrieb:

    Roger Wilco schrieb:

    Der Compiler könnte aber das Vorzeichen auswerten und warnen anstatt einfach nur in hex zuzuweisen.

    Tut er ja auch. Er gibt immer eine Warnung aus, wenn ein signed Datentyp einem unsinged Datentyp zugewiesen wird. Aber da es nur eine Warnung ist muss er weitermachen und irgendwas tun - z.B. den entsprechenden Hex-Wert zuweisen.

    Bei mir (VC6.0) nicht (Warnstufe 4):

    #include <iostream>
    
    void foo(unsigned int i){
        std::cout << "foo: " << i << std::endl;
    }
    
    int main(int argc, char* argv[])
    {	
        unsigned int i = -1;
        std::cout << "main: " << i << std::endl;
        foo(-5);
        return 0;
    }
    

    VC6.0: schrieb:

    Kompilierung läuft...
    Test.cpp
    Linker-Vorgang läuft...

    Test.exe - 0 Fehler, 0 Warnung(en)

    Ausgabe: schrieb:

    main: 4294967295
    foo: 4294967291

    sicher, dass du warninglvl 4 hast?
    ich hab zwar die 9.0, aber dachte, dass auch die 6.0 da scho gewarnt hätte...

    MSVC 2008 schrieb:

    1>c:\...\main.cpp(9) : warning C4245: 'initializing' : conversion from 'int' to 'unsigned int', signed/unsigned mismatch
    1>c:\...\main.cpp(11) : warning C4245: 'argument' : conversion from 'int' to 'unsigned int', signed/unsigned mismatch
    1>c:\...\main.cpp(7) : warning C4100: 'argv' : unreferenced formal parameter
    1>c:\...\main.cpp(7) : warning C4100: 'argc' : unreferenced formal parameter

    1>test - 0 error(s), 4 warning(s)

    und mich würd es sehr wundern, wenn die 6.0 auch noch nicht vor "unreferenced formal parameter" gewarnt hätte...

    bb



  • Bashar schrieb:

    Da steht kongruent modulo 2^n. Mal ein Beispiel. Du hast die Zahl -200 und möchtest sie in unsigned char (mit CHAR_BIT=8) speichern. 2^8 ist 256. Genau die Zahlen -200 + k*256 (k ganze Zahl) sind also (modulo 256) kongruent zu -200, nur die nichtnegativen Zahlen sind interessant, also 56, 312, 568, 824, ..., und davon die kleinste ist 56.
    Man hätte das "least" weglassen können, weil von diesen Zahlen sowieso immer nur eine im Zieltyp darstellbar ist.

    Danke für die Erklärung, ich kannte das mathematische Kongruent nicht.

    unskilled schrieb:

    sicher, dass du warninglvl 4 hast?

    Nee stimmt, hast recht. Ich Dussel habe erst Erstellt, dann /W3 auf W4 umgestellt und nochmals übersetzt, was dann die Warnungen natürlich übersprungen hat.

    VC++ 6.0 gibt Warnung bei WarnLevel 4 aus:

    D:\Software-Entwicklung\testw\testw.cpp(8) : warning C4245: 'initializing' : Konvertierung von 'const int' in 'unsigned int', signed/unsigned-Konflikt
    D:\Software-Entwicklung\testw\testw.cpp(6) : warning C4100: 'argv' : Unreferenzierter formaler Parameter
    D:\Software-Entwicklung\testw\testw.cpp(6) : warning C4100: 'argc' : Unreferenzierter formaler Parameter
    D:\Software-Entwicklung\testw\testw.cpp(8) : warning C4189: 'i' : Lokale Variable ist initialisiert aber nicht referenziert


Anmelden zum Antworten