Skalare Datentypen - irgendeine Verlässlichkeit?



  • boost to the rescue: http://www.boost.org/doc/libs/1_37_0/libs/integer/index.html

    und ab C++0x ist <cstdint> dann ja sogar ein offizieller Header 🙂



  • Naja, aber mir ging es ja eher um die Built-Ins.

    Benutzt ihr trotz allem immer int , short , etc.? Oder bei allen unsigned-Typen size_t ? Oder die <cstdint>- bzw. <stdint.h>-Typen?

    Ich finde es einfach ein wenig fragwürdig, dass die Sprache Typen bereitstellt, von denen erwartet wird, dass man mit ihnen arbeitet, aber gleichzeitig kann man sich dabei nie ganz sicher sein...



  • Nexus schrieb:

    Naja, aber mir ging es ja eher um die Built-Ins.

    Benutzt ihr trotz allem immer int , short , etc.? Oder bei allen unsigned-Typen size_t ? Oder die <cstdint>- bzw. <stdint.h>-Typen?

    size_t, etc. wenn es vom Kontext her Sinn macht.

    Nexus schrieb:

    Ich finde es einfach ein wenig fragwürdig, dass die Sprache Typen bereitstellt, von denen erwartet wird, dass man mit ihnen arbeitet, aber gleichzeitig kann man sich dabei nie ganz sicher sein...

    Du kannst dir sicher sein. Wie schon gesagt. char hat mindestens 8 Bit, short mindestens 16 und long mindestens 32. Sie dürfen natürlich größer sein. Aber das sollte in fast allen Fällen nicht schlimm sein.

    Wenn du int verwendest, wird dir was anderes garantiert. Und zwar, dass (soweit ich mich erinnere) er mindestens so lang wie short ist. Und dass er den nativen Integertyp des Prozessors wiederspiegelt. Also das beste ist, womit der Prozessor umgehen kann (unter der Voraussetzung, dass er halt mit mind. 16-Bit umgehen kann).

    Das ist doch eigentlich recht vernünftig. Eine gewisse Sache ist garantiert, aber es kann auch besser sein.



  • ProgChild schrieb:

    Nexus schrieb:

    Ich finde es einfach ein wenig fragwürdig, dass die Sprache Typen bereitstellt, von denen erwartet wird, dass man mit ihnen arbeitet, aber gleichzeitig kann man sich dabei nie ganz sicher sein...

    Du kannst dir sicher sein. Wie schon gesagt. char hat mindestens 8 Bit, short mindestens 16 und long mindestens 32. Sie dürfen natürlich größer sein. Aber das sollte in fast allen Fällen nicht schlimm sein.

    Ich glaube in dem Fall zwar einmal, dass Stroustrup da nichts falsches geschrieben hat, aber im Standard konnte ich von diesen Werten nichts finden.
    Wie gesagt die einzige Garantie, die ich gefunden habe, ist, dass char mindestens 8 Bit haben muss, damit es das Characterset halten kann.



  • Die Mindestgrößen werden indirekt über die Mindesgrößen von den *_MAX und *_MIN Konstanten aus climits garantiert. SHRT_MAX muss z.B. mindestens 32767 groß sein. Die Mindestgröße für short ist also 16-bit.

    Gruß
    Don06





  • drakon schrieb:

    Ich glaube in dem Fall zwar einmal, dass Stroustrup da nichts falsches geschrieben hat, aber im Standard konnte ich von diesen Werten nichts finden.
    Wie gesagt die einzige Garantie, die ich gefunden habe, ist, dass char mindestens 8 Bit haben muss, damit es das Characterset halten kann.

    Ich hab auch gerade im Standard gewühlt und nichts gefunden. Aber ich hab auch die 800 Seiten nicht komplett gelesen 😃

    Ich hab das aber auch irgenwo gelesen, dass das mit den Variablen so garantiert ist.



  • ProgChild schrieb:

    Wenn du int verwendest, wird dir was anderes garantiert. Und zwar, dass (soweit ich mich erinnere) er mindestens so lang wie short ist. Und dass er den nativen Integertyp des Prozessors wiederspiegelt. Also das beste ist, womit der Prozessor umgehen kann (unter der Voraussetzung, dass er halt mit mind. 16-Bit umgehen kann).

    Das heisst, int sollte man um sicher zu gehen nur nutzen, wenn man gerade so gut short nutzen könnte. Naja, dann habe ich das bisher etwas missachtet. Naja... 😉

    Don06 schrieb:

    Die Mindestgrößen werden indirekt über die Mindesgrößen von den *_MAX und *_MIN Konstanten aus climits garantiert. SHRT_MAX muss z.B. mindestens 32767 groß sein. Die Mindestgröße für short ist also 16-bit.

    Okay. Wo findet man dann die tatsächlichen Grössen? Sind die Werte in <limits> eigentlich immer genau die gleichen wie die in <climits> ?



  • Wie "portabel" willst du denn programmieren und warum interessiert dich das so genau wie groß ein Datentyp ist? Wenn du für normale Windows,Linux oder Mac PCs programmierst, sind die doch sogut wie gleich groß und es ist egal. Wenn du für embedded Hardware programmierst weiß du auch wie groß dort die Datentypen sind. Ich vesteh nicht was da so ein großes Problem ist.



  • sagmal schrieb:

    Wie "portabel" willst du denn programmieren und warum interessiert dich das so genau wie groß ein Datentyp ist?

    Weil es von Vorteil wäre, wenn ich meine Programme nicht mühsam durchforsten und Typen ersetzen müsste, wenn ich sie mal auf einer anderen Plattform zum Laufen bringen will.

    sagmal schrieb:

    Wenn du für normale Windows,Linux oder Mac PCs programmierst, sind die doch sogut wie gleich groß und es ist egal.

    Das würde ich nicht sagen. Meines Wissens haben doch bereits die verschiedenen Compiler/IDEs unterschiedliche Typen. Unterscheiden sich nicht bereits MSVC++ und Code::Blocks, zum Beispiel bezüglich long double ?



  • Nexus schrieb:

    sagmal schrieb:

    Wie "portabel" willst du denn programmieren und warum interessiert dich das so genau wie groß ein Datentyp ist?

    Weil es von Vorteil wäre, wenn ich meine Programme nicht mühsam durchforsten und Typen ersetzen müsste, wenn ich sie mal auf einer anderen Plattform zum Laufen bringen will.

    sagmal schrieb:

    Wenn du für normale Windows,Linux oder Mac PCs programmierst, sind die doch sogut wie gleich groß und es ist egal.

    Das würde ich nicht sagen. Meines Wissens haben doch bereits die verschiedenen Compiler/IDEs unterschiedliche Typen. Unterscheiden sich nicht bereits MSVC++ und Code::Blocks, zum Beispiel bezüglich long double ?

    was für Programme schreibst du denn, dass es so wichtig ist, dass du die Datentypen immer voll ausnutzen kannst und sogar long double brauchst?



  • Aus meinem ersten Post sollte der Beweggrund für diesen Thread ersichtlich sein.



  • Nexus schrieb:

    Und weshalb hat der C++-Standard diesbezüglich nicht mehr Vorschriften gemacht? Dass int oft den für die Plattform am besten ausgerichteten Datentypen repräsentiert, ist ja schön und gut, aber etwas vage...

    Das hängt alles von C ab.
    Aber etwas aus der C++ Norm.
    § 3.9.1 Absatz 2
    kann man folgende Reihenfolge schließen
    sizeof(signed char) <= sizeof(short) <= sizeof(int) <= sizeof(long int)
    Absatz 3 ditto für vorzeichenlose Typen

    Desweiteren ist ISO 9899:2001 § 5.2.4.2.1 zu beachten

    CHAR_BIT >= 8
    SCHAR_MIN <= -127
    SCHAR_MAX >= 127
    UCHAR_MAX >= 255
    SHRT_MIN <= -32767
    SHRT_MAX >= 32767
    USHRT_MAX >= 65535
    INT_MIN <= -32767
    INT_MAX >= 32767
    UINT_MAX >= 65535
    LONG_MIN <= -2147483647
    LONG_MAX >= +2147483647
    ULONG_MAX >= 4294967295
    LLONG_MIN <= -9223372036854775807
    LLONG_MAX >= 9223372036854775807
    ULLONG_MAX >= 18446744073709551615
    

    Wenn diese Aussagen nicht ausreichen, dann muß man sich mit <stdint.h> auseinandersetzen. Es gibt darin Datentypen mit exakten Bitgrößen und Datentypen mit mindestens n-Bitgröße.
    Folgendes muß definiert sein.

    int_least8_t
    int_least16_t
    int_least32_t
    int_least64_t
    uint_least8_t
    uint_least16_t
    uint_least32_t
    uint_least64_t
    

    Falls die Integer-Typen mit 8, 16, 32 und 64Bitgröße als Standardtypen existieren, muß es die folgenden typedefs geben.
    int8_t, uint8_t, ... , int64_t, uint64_t

    Folgendes muß wiederrum definiert sein

    int_fast8_t
    int_fast16_t
    int_fast32_t
    int_fast64_t
    uint_fast8_t
    uint_fast16_t
    uint_fast32_t
    uint_fast64_t
    

    Wenn Dir das nicht genügt, dann kannst Du Dich auf die SUS V3 (Single UNIX Spec V3) beziehen (keine Ahnung was für Garantien Windows macht). Natürlich läuft dann Dein Programm nur noch garantiert auf einer SUS V3 Plattform.

    SUSV3 definiert im Prinzip zwei Laufzeitumgebungen ILP32 und LP64.
    Auszug aus "The UNIX System Today" (SUS V2)
    sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(size_t)
    Die typedefs int8_t, int16_t, int32_t (und korrespondierende uint) sind definiert, falls _POSIX_V6_ILP32_OFFBIG, _POSIX_V6_LP64_OFF64 oder _POSIX_V6_LPBIG_OFFBIG definiert wurden ist auch uint64_t bzw. int64_t definiert.

    ILP32 definiert die Bit größen der Typen wie folgt:
    char 8, short 16, int 32, long 32, pointer 32
    LP64:
    char 8, short 16, int 32, long 64, pointer 64

    Es gibt die Möglichkeit, daß ein 64Bit Type im ILP32 Modus definiert ist, aber das hängt dann von bestimmten Makros ab, dazu bitte die SUS lesen.



  • Vielen Dank für die ausführliche Antwort, ~john! Das ist echt interessant, vieles davon habe ich nicht gewusst.

    Wenn man jetzt char , short und long für Integer nutzt, sollte man die Grösse eigentlich relativ gut eingrenzen können. Ansonsten die <stdint.h>-Typen... Danke für eure Bemühungen!



  • int ist nicht der "native" Datentyp des Prozessors.

    (1) Der Begriff an sich ist schon relativ sinnfrei, weil es dem x86 oder x86-64 egal ist, ob er jetzt mit dem 8, 16, 32 Teil des Registers rechnet. Die Größen sind alle "native" weil sie alle im Assembler direkt als Operand angegeben werden können (es muss nicht zum Beispiel ein 16Bit Wert vorher in ein 32 Bit Register kopiert werden, welches dann mit Nullen aufgefüllt wird).

    (2) Wenn man diesen Begriff trotzdem verwendet, müsste ein int für den x86-64 ja 64 Bit haben, ich kennen keinen Compiler der das so macht. Der g++ und VC++ jedenfalls nicht.



  • Optimizer schrieb:

    int ist nicht der "native" Datentyp des Prozessors.

    (1) Der Begriff an sich ist schon relativ sinnfrei, weil es dem x86 oder x86-64 egal ist, ob er jetzt mit dem 8, 16, 32 Teil des Registers rechnet. Die Größen sind alle "native" weil sie alle im Assembler direkt als Operand angegeben werden können (es muss nicht zum Beispiel ein 16Bit Wert vorher in ein 32 Bit Register kopiert werden, welches dann mit Nullen aufgefüllt wird).

    (2) Wenn man diesen Begriff trotzdem verwendet, müsste ein int für den x86-64 ja 64 Bit haben, ich kennen keinen Compiler der das so macht. Der g++ und VC++ jedenfalls nicht.

    Andersherum wird ein Schuh draus. Compilierst du für einen 16-Bit-Prozessor wird int wohl kaum 32-Bit groß sein. Compilierst du für einen 32-Bit Prozessor, wird int wohl kaum 64-Bit groß sein. Und auf einem 16-Bit System kann sehr wohl der Datentyp long vorhanden sein.

    Die Welt besteht ja nicht nur aus x86 und x64.


Anmelden zum Antworten