size_t Overflow erkennen



  • std::size_t kann schlicht für alle Speichergrößen verwendet werden und ist eigentlich immer exakt so groß, um jedes Byte das der Prozessor addressieren kann auch selbst darstellen könnte. Wären unter 64bit immerhin 16.777.216 Terrabyte, also genug. 😉



  • Ethon schrieb:

    std::size_t kann schlicht für alle Speichergrößen verwendet werden und ist eigentlich immer exakt so groß, um jedes Byte das der Prozessor addressieren kann auch selbst darstellen könnte. Wären unter 64bit immerhin 16.777.216 Terrabyte, also genug. 😉

    Muß nicht sein. Stell Dir DOS vor mit einem Speichermodell, wo kein Objekt größer als 64k sein kann, aber Zeiger 32-bittig sind.
    Desdawegen ist ja auch die Adressvergleicherei in C++ nicht garantiert, wenn man Zeiger aus verschiedenen Objekten vergleicht.

    Aber faktisch kann man davon ausgehen. Da reicht es sogar, wie ich eingangs sagte, gegen 0 zu prüfen (also (sizeof(Element)<<n)==0 mit einer Zweierpotenz als sizeof(Element)).


  • Mod

    volkard schrieb:

    Da reicht es sogar, wie ich eingangs sagte, gegen 0 zu prüfen (also (sizeof(Element)<<n)==0 mit einer Zweierpotenz als sizeof(Element)).

    Nicht zu empfehlen.

    C++11 schrieb:

    5.8 Shift operators [expr.shift]
    1 The shift operators << and >> group left-to-right.
    shift-expression:
    additive-expression
    shift-expression << additive-expression
    shift-expression >> additive-expression
    The operands shall be of integral or unscoped enumeration type and integral promotions are performed.
    The type of the result is that of the promoted left operand. The behavior is undefined if the right operand
    is negative, or greater than or equal to the length in bits of the promoted left operand.



  • Danke schonmal für die vielen Antworten, der Thread hat mir schon ein wenig geholfen, mein Wissen zu erweitern.

    Noch eine kurze Frage zu dem <<-Operator. Wie verhält es sich hier mit impliziten Typedefs?

    Angenommen: Ich schreibe a << b, wobei a ein Short ist und b ein unsigned long? Das hat insofern Relevanz, dass der Ausdruck bei short einen Overflow geben könnte, während er bei unsigned long keine Probleme verursacht. Was ist, wenn ich links ein Literal stehen habe? Welchen Typ hat dann der Ausdruck 1<<n? Kann ich davon ausgehen, dass er den gleichen Typ hat wie n?

    Die gleiche Frage stellt sich bei mir gerade mit Addition:
    Angenommen, ich habe eine int a und eine unsigned long b und berechne a + b. Eigentlich müsste das Ergebnis Typ int haben, da dabei eben auch negative Werte auftreten können. Wäre andererseits aber etwas paradox, denn man könnte dann ja einfach Overflows produzieren, selbst wenn a zB den Wert 0 hat (und b größer als max_int ist).

    Übrigens kann man sich das mit CHAR_BITS wohl auch sparen, wenn man die Funktion digits aus limits.h benutzt: [Return-Wert] For integer types: number of non-sign bits (radix base digits) in the representation.



  • plizzz schrieb:

    Angenommen, ich habe eine int a und eine unsigned long b und berechne a + b. Eigentlich müsste das Ergebnis Typ int haben, da dabei eben auch negative Werte auftreten können.

    Der Typ ist unsigned long.
    Die Regeln nach denen das abläuft stehen z.B. hier:
    http://msdn.microsoft.com/en-us/library/09ka8bxx(v=VS.80).aspx



  • Okay danke. DAs ist gut zu wissen und ergibt Sinn.



  • Ich grade den Thread mal wieder aus. Und zwar ist es nun so, dass size_t bei mir 32 bits groß ist, ich allerdings ein 64-Bit System habe. Steht das nicht im Widerspruch zur Idee von size_t?



  • plizzz schrieb:

    Ich grade den Thread mal wieder aus. Und zwar ist es nun so, dass size_t bei mir 32 bits groß ist, ich allerdings ein 64-Bit System habe. Steht das nicht im Widerspruch zur Idee von size_t?

    Du kompilierst im 64bit Modus?



  • Darüber habe ich mir noch gar keine Gedanken gemacht - ich kompiliere einfach, sozusagen. Aber das wird dann wohl nicht der 64bit Modus sein und damit ist die Frage dann geklärt. Heißt das dann auch, dass so Dinge wie sizeof(Datentyp), CHAR_BIT, INT_MAX, ... beim Zeitpunkt der Kompilierung und nicht während der Laufzeit festgelegt werden?



  • plizzz schrieb:

    Darüber habe ich mir noch gar keine Gedanken gemacht - ich kompiliere einfach, sozusagen. Aber das wird dann wohl nicht der 64bit Modus sein und damit ist die Frage dann geklärt. Heißt das dann auch, dass so Dinge wie sizeof(Datentyp), CHAR_BIT, INT_MAX, ... beim Zeitpunkt der Kompilierung und nicht während der Laufzeit festgelegt werden?

    ja



  • Ethon schrieb:

    Wären unter 64bit immerhin 16.777.216 Terrabyte, also genug. 😉

    Das heißt Terabyte und nicht Terrabyte.



  • plizzz schrieb:

    Welchen Typ hat dann der Ausdruck 1<<n? Kann ich davon ausgehen, dass er den gleichen Typ hat wie n?

    Hier greift die arithmetic promotion, defaultmäßig rechnet C mit int.
    Nein. Deshalb verwendet man sinnigerweise auch 1UL<<n bzw. 1ULL<<n.



  • Wutz schrieb:

    Das heißt Terabyte und nicht Terrabyte.

    Dafür gibts mal ein fettes +1.



  • Wutz schrieb:

    plizzz schrieb:

    Welchen Typ hat dann der Ausdruck 1<<n? Kann ich davon ausgehen, dass er den gleichen Typ hat wie n?

    Hier greift die arithmetic promotion, defaultmäßig rechnet C mit int.
    Nein. Deshalb verwendet man sinnigerweise auch 1UL<<n bzw. 1ULL<<n.

    Vielen Dank für den Hinweis. Ich kannte die Typbestimmungen bei Literalen gar nicht.


Anmelden zum Antworten