überlaufe im c++-standard



  • wie verhält sich c++ nach dem ansi-standard bei überläufen von ganzzahlen?

    wenn ich das beispiel unten mit visual studio .net kompiliere und ausführe ist der test erfolgreich und der überlauf wird abgefangen. allerdings auch nur weil chars und shorts in 32 bit variablen umgewandelt werden (und da dann kein überlauf stattfindet). wenn ich das selbe beispiel mit unsigned long's mache, dann funktioniert es nicht mehr. mann muss dann die konvertierung in eine größere variable von hand vornehmen...

    das funktionier so wie es soll, sowohl mit chars als auch mit shorts
    
        unsigned char I1;
        unsigned char I2;
    
        I1=0xfa;
        I2=0xfa;
    
        if ((I1+I2)>0xff) printf("TEST OK\n");
    
    shorts...
    
        unsigned short I1;
        unsigned short I2;
    
        I1=0xfffa;
        I2=0xfffa;
    
        if ((I1+I2)>0xffff) printf("TEST OK\n");
    
    das funktioniert nicht :(
    
        unsigned long I1;
        unsigned long I2;
    
        I1=0xfffffffa;
        I2=0xfffffffa;
    
        if ((I1+I2)>0xffffffff) printf("TEST OK\n");
    
    nur wenn man nachhilft funktioniert's:
    
        unsigned long I1;
        unsigned long I2;
    
        I1=0xfffffffa;
        I2=0xfffffffa;
    
        if (((__int64)I1+(__int64)I2)>0xffffffff) printf("TEST OK\n");
    

    wie ist nun dieses überlaufverhalten im c++-standard definiert?

    sollte man bei jeder addition zweier zahlen, bei denen es möglich ist, dass ein überlauf stattfindet eine typumwandlunbg in einen größeren typ machen? oder kann man sich darauf verlassen, das der kompiler das macht? gibt es da irgendwelche regeln? weiss jemand wo mann die genaue spezifikation des c++-standards nachlesen kann?

    [ Dieser Beitrag wurde am 10.05.2003 um 18:43 Uhr von KXII editiert. ]



  • Den C++ Standard kannst du dir bei der ANSI kaufen.

    http://webstore.ansi.org/ansidocstore/default.asp
    C++-Standard (ISO/IEC 14882-1998); Format PDF; ca. 2,8 MB, 776 Seiten, Kosten: US$ 18,-. Akzeptierte Kreditkarten: VISA, MasterCard, American Express. Vor Bezahlung und Download ist eine umständliche Registrierungsprozedur zu durchlaufen.



  • das ist kostenlos und zu 98% mit den standard gleich http://www.kuzbass.ru/docs/isocpp/

    zu der frage mit den überlaufen: ich wette das ist undefiniert

    um überleufte zu verhindern muss du aber nicht in einen grösseren typ casten das geht einfach so

    #include <limits>
    
    int main()
    {
        int a = 0xFFFFFF;
        int b = 0xFFFFFF;
    
        if((std::numeric_limits<int>::max() - a) < b)
            // wenn du b und a addierst wirds überlaufen
    }
    

    [ Dieser Beitrag wurde am 11.05.2003 um 00:50 Uhr von Dimah editiert. ]



  • das casten ist aber einfacher gerade bei längeren ausdrücken:

    Length=Length+(unsigned long)AAALength+(unsigned long)BBBLength+(unsigned long)CCCLength; 
    //hier kann man dann bis zu 65536 einzelne werte addieren bis ein 32bit überlauf sattfindet, das sollte genügen
    
    if (Length>0xffff)
    {
      Length=0xffff;
      break;
    }
    
    und dann hier zurückcasten:
    
    MyUnsignedShortResult=(unsigned short)Length;
    
    // wenn Length ein unsigned long ist und die einzelnen Length's alle unsigned 
    // shorts, dann ist es so einfacher, weil ich ansonsten jede addition einzeln 
    // überprüfen müsste, und zwar folgendermaßen:
    
    if ((0xffff-Length)<AAALength))
    {
      Length=0xffff;
    }
    else
    {
      Length=Length+AAALength;
    
      if ((0xffff-Length)<BBBLength))
      {
        Length=0xffff;
      }
      else
      {
        Length=Length+BBBLength;
    
        if ((0xffff-Length)<CCCLength))
        {
          Length=0xffff;
        }
        else
        {
          Length=Length+CCCLength;
        }
      }
    }
    

    mir gefällt meine version besser. ausserdem ist sie schneller, weil die überprüfung wegfällt. (die ist echt überflüssig!!!) wenn du ahnung von assembler hast dann müsstest du wissen, dass man auch x-bit-zahlen aus 2 (x/2)-bit-zahlen darstellen kann (zumindest auf allen x86er und pentium prozessoren).

    z.b. 64 bit variablen werden mit 2 32bit variablen dargestellt. so arbeiten unter anderem auch die mul und div befehle des prozessors!

    mein frage ist eigentlich nur, ob der c++-standard diese interene umwandlung selber vornimmt und wenn ja bis zu welchen größen. in visual studio .net gehts bis 16bit. ist das jetzt zufall oder ist das so definiert ?!? 😕

    ich werde mir mal deinen linka anschauen

    /edit zeilenumbrücher reingemacht

    [ Dieser Beitrag wurde am 11.05.2003 um 13:38 Uhr von Dimah editiert. ]


Anmelden zum Antworten