pl: C mal wieder, Länge einer Binary

Moin, s. Thema. Problem:

    char bin[] = {0,0,0,0};
    printf("%d\n", strlen(bin) );

ergibt Länge 0. Also strlen() ist da ungeeignet das rauszukriegen. Welche Möglichkeiten gibt es dann?

MfG, schönen Sonntag.

  1. Hallo,

    hast du mal sizeof ausprobiert?

    Gruß
    Jürgen

    1. Hallo,

      hast du mal sizeof ausprobiert?

      Ja grad eben, haut hin 😉

      Danke Dir!

      1. Hello,

        hast du mal sizeof ausprobiert?

        Ja grad eben, haut hin 😉

        Wenn Du die Anzahl der Elemente wissen willst, kommt es aber darauf an, mit wieviel Bytes char auf dem System definiert wird. Das würde ich an dieser Stelle immer vollständig programmieren, damit es keine Portabilitätsprobleme gibt.

        Glück Auf
        Tom vom Berg

        --
        Es gibt nichts Gutes, außer man tut es!
        Das Leben selbst ist der Sinn.
        1. Hallo Tom,

          da ist die Frage, welche Länge gewünscht ist: Zahl der Bytes oder Zahl der Arrayelemente. Für letzteres kann man sizeof(Array)/sizeof(Element) nehmen.

          Gruß
          Jürgen

          1. Hello Jürgen,

            da ist die Frage, welche Länge gewünscht ist: Zahl der Bytes oder Zahl der Arrayelemente. Für letzteres kann man sizeof(Array)/sizeof(Element) nehmen.

            Das schrieb ich schon.

            Man sollte nur KEINESFALLS annehmen, dass char immer nur mit einem Byte festgelegt ist auf allen Systemen!

            Glück Auf
            Tom vom Berg

            --
            Es gibt nichts Gutes, außer man tut es!
            Das Leben selbst ist der Sinn.
        2. Wenn Du die Anzahl der Elemente wissen willst, kommt es aber darauf an, mit wieviel Bytes char auf dem System definiert wird.

          Es muss systemabhängig sein. Von daher arbeite ich auch mit uint8_t anstelle unsigned char. Letztendlich gehts darum, eine bestimmte Anzahl an Bytes aus einem Socket zu lesen. Wäre ja schlimm, wenn jedes System unter einem Byte was anderes versteht!

          Mel eben nachgprüft: recv() gibt die Anzahl der gelesenen Bytes zurück und das ist unabhängig davon, welche Länge (in bytes) der Puffr hatte der da übergeben wurde.

          Anfragen an Nameserver müssen bytegenau stimmen und dasselbe gilt für die Response!

          MfG

    2. Hallo JürgenB,

      hast du mal sizeof ausprobiert?

      Achtung: das funktioniert nur für statische Buffer, also für Buffer, deren Größe zur Compile-Zeit bekannt ist.

      Bei Buffern auf dem Heap muss man das halt wissen.

      LG,
      CK

  2. Hello,

        char bin[] = {0,0,0,0};
        printf("%d\n", strlen(bin) );
    

    ergibt Länge 0. Also strlen() ist da ungeeignet das rauszukriegen. Welche Möglichkeiten gibt es dann?

    printf("d\r\n", sizeof(abin) / sizeof(char));

    Das sollte die Anzahl der Elemente des Arrays ergeben. Wolltest Du die wissen?
    Ich habe jetzt extra abin geschrieben, weil ich bei C immer nicht weiß, welche Bezeichner reserviert sind.

    Glück Auf
    Tom vom Berg

    --
    Es gibt nichts Gutes, außer man tut es!
    Das Leben selbst ist der Sinn.
  3. Hallo pl,

    Also strlen() ist da ungeeignet das rauszukriegen.

    Ja, weil es beim ersten Nullbyte aufhört zu zählen.

    Rolf

    --
    sumpsi - posui - clusi
    1. Hello,

      Also strlen() ist da ungeeignet das rauszukriegen.

      Ja, weil es beim ersten Nullbyte aufhört zu zählen.

      Wenn bin ein Array of Char (je 1 Byte) ist, ist das dann identisch mit bin[0], oder würde sizeof() quasi die Länge der Adresse prüfen bis zum ersten NULL-Byte?

      Glück Auf
      Tom vom Berg

      --
      Es gibt nichts Gutes, außer man tut es!
      Das Leben selbst ist der Sinn.
      1. Moin Tom,

        Wenn bin ein Array of Char (je 1 Byte) ist, ist das dann identisch mit bin[0], oder würde sizeof() quasi die Länge der Adresse prüfen bis zum ersten NULL-Byte?

        Weder noch: sizeof ermittelt die Größe eines Objects:

        char bin[] = { 0, 0, 0, 0 };
        printf("%lu\n", sizeof(bin));  /* gibt 4 × sizeof(char) aus */
        

        Viele Grüße
        Robert

        1. Hello,

          ach, ich meinte doch strlen()…

          Glück Auf
          Tom vom Berg

          --
          Es gibt nichts Gutes, außer man tut es!
          Das Leben selbst ist der Sinn.
          1. Moin Tom,

            ach, ich meinte doch strlen()…

            Das Verhalten von strlen ist genau definiert:

            Returns the length of the given null-terminated byte string, that is, the number of characters in a character array whose first element is pointed to by str up to and not including the first null character.

            Viele Grüße
            Robert

            1. Hello,

              ach, ich meinte doch strlen()…

              Das Verhalten von strlen ist genau definiert:

              Returns the length of the given null-terminated byte string, that is, the number of characters in a character array whose first element is pointed to by str up to and not including the first null character.

              Danke.

              Bleibt nur noch die Frage, was da formal bei der Initialisierung eingetragen wird in die vier Elemente.

              char bin[] = {0,0,0,0};

              Ist das oktal 0? Stringrepräsentationen sind es ja nicht.

              Glück Auf
              Tom vom Berg

              --
              Es gibt nichts Gutes, außer man tut es!
              Das Leben selbst ist der Sinn.
              1. Das sind Bytes die mit der Wertigkeit 0 initialisiert werden. MfG

                PS: Beim Serialisieren einer Nameserver Anfrage spielen diese Bytes eine wichtige Rolle. U.a. ist die Länge eines Labels, z.b. die authority (wie example) auf 255 begrenzt, weil diese Länge mit nur einem Byte kodiert wird.

              2. Hallo TS,

                Bleibt nur noch die Frage, was da formal bei der Initialisierung eingetragen wird in die vier Elemente.

                char bin[] = {0,0,0,0};

                Das ist ein Array mit vier Elementen, alle mit dem Wert 0.

                Ist das oktal 0?

                Streng genommen ist es eine dezimale 0.

                Stringrepräsentationen sind es ja nicht.

                Ich weiß nicht, was du damit meinst.

                LG,
                CK

                1. Hello,

                  Bleibt nur noch die Frage, was da formal bei der Initialisierung eingetragen wird in die vier Elemente.

                  char bin[] = {0,0,0,0};

                  Das ist ein Array mit vier Elementen, alle mit dem Wert 0.

                  Ist das oktal 0?

                  Streng genommen ist es eine dezimale 0.

                  Stringrepräsentationen sind es ja nicht.

                  Ich weiß nicht, was du damit meinst.

                  char bin[] = {'0','0','0','0'};

                  Ich nehme an, dass strlen() so eventuell 4 als Ergebnis geliefert hätte, wenn hinter dem Array im Speicher zufällig NULL gestanden hätte.

                  Darf man denn strlen() überhaupt auf den Datentyp char anwenden? Das widerspricht doch der zitierten Definition.

                  Glück Auf
                  Tom vom Berg

                  --
                  Es gibt nichts Gutes, außer man tut es!
                  Das Leben selbst ist der Sinn.
                  1. Hallo TS,

                    { 0,0,0,0 } und { '0','0','0','0'') sind verschiedene Dinge. Die dezimale Entsprechung des zweiten Initializers wäre { 48,48,48,48 }.

                    strlen darf man nicht auf den Datentyp char anwenden. Aber das tust Du ja nicht. Du wendest ihn auf char[] an, was zur Laufzeit identisch zu char* ist. Der Unterschied besteht zur Compilezeit:

                    char x[100];
                    char* y;
                    
                    printf("%d %d", sizeof(x), sizeof(y));
                    

                    Die Ausgabe ist 100 4 (auf einem 32-bit System) oder 100 8 (auf einem System mit 64-bit Pointern). Vielleicht auch 200 8 oder 400 8, wenn das System für Unicode Zeichen ausgelegt ist; ich weiß aber nicht ob es das gibt. Typischerweise verwendet man dann wchar_t, das von den beim Compiler mitgeieferten includes (wchar.h) per typedef konstruiert wird. Der Online C Compiler von tutorialspoint.com hat sizeof(wchar_t) == 4.

                    Rolf

                    --
                    sumpsi - posui - clusi
                    1. Hello,

                      das bestätigt meine Annahme, dass Rolfs Löcherproduktion durchaus noch ungeahnte Entwicklungen annehmen kann. Und es verstärkt meinen Widerwillen gegen C und ähnlich schw(a|i)mmige Sprachen.

                      Glück Auf
                      Tom vom Berg

                      --
                      Es gibt nichts Gutes, außer man tut es!
                      Das Leben selbst ist der Sinn.
                    2. Hello,

                      { 0,0,0,0 } und { '0','0','0','0'') sind verschiedene Dinge. Die dezimale Entsprechung des zweiten Initializers wäre { 48,48,48,48 }.

                      Das gilt aber nur für C auf OS, die mit ASCII arbeiten. Bei EBCDIC müsste 0xf0 drinstehen. Ich kann mich jedenfalls noch dran erinnern, dass ich in meinen erten Konvertierprogrammen zwischen Sys36/AS400 und PCs immer geschwitzt habe.

                      Das war der Grund, dass ich "vollständige Programmierung" angemahnt hatte.

                      Glück Auf
                      Tom vom Berg

                      --
                      Es gibt nichts Gutes, außer man tut es!
                      Das Leben selbst ist der Sinn.
                      1. Hallo TS,

                        EBCDIC, alter Hosti, hast schon recht...

                        Aber '0' ist für einen String aus Nullbytes eh die falsche Lösung.

                        Rolf

                        --
                        sumpsi - posui - clusi
                    3. Moin,

                          char *c = "a";
                          printf("%d %d", sizeof c, strlen(c));
                                            4          1
                      

                      4 ist die Byte-Länge des Pointers, 4*8 = 32 Bit , das ist das was meine Kiste hergibt. 1 heißt ein Byte. Wenn ich da ein ä reinsetze sind es 2 Bytes (utf8).

                      Richtig?

                      1. Hallo pl,

                        Wenn ich da ein ä reinsetze sind es 2 Bytes (utf8).

                        Wenn dein Editor UTF8 codiert, ja. Codiert er CP850 oder ISO 8859-x, dann nicht.

                        Rolf

                        --
                        sumpsi - posui - clusi
                      2. Moin,

                        char *c = "a";
                        printf("%d %d", sizeof c, strlen(c));
                                              4          1
                        

                        4 ist die Byte-Länge des Pointers, 4*8 = 32 Bit , das ist das was meine Kiste hergibt. 1 heißt ein Byte. Wenn ich da ein ä reinsetze sind es 2 Bytes (utf8).

                        Richtig?

                        Bei UTF-8, ja – abgesehen davon, dass %d die falsche Formatangabe für size_t ist! Wie oft soll man dir das eigentlich noch erklären, bis du mal einen size_t hast, der $$\ge 2^{31}$$ ist?!

                        Aber um die Verwirrung noch etwas zu steigern:

                        char c[] = "a";
                        printf("%lu %lu\n", sizeof c, strlen(c));
                                               2         1
                        

                        Viele Grüße
                        Robert

                        1. Hallo Robert,

                          abgesehen davon, dass %d die falsche Formatangabe für size_t ist!

                          Nein, es ist der richtige. Es fehlt nur der length modifier z:

                          Length modifier

                          Here, "integer conversion" stands for d, i, o, u, x, or X conversion. […]

                          • z A following integer conversion corresponds to a size_t or ssize_t argument, or a following n conversion corresponds to a pointer to a size_t argument.

                          Das richtige Format für size_t ist "%zd" (bzw "%zx" wenn der Wert hexadezimal dargestellt werden soll).

                          Wie oft soll man dir das eigentlich noch erklären, bis du mal einen size_t hast, der $$\ge 2^{31}$$ ist?!

                          Ja, der length modifier z sollte wirklich nicht fehlen.

                          char c[] = "a";
                          printf("%lu %lu\n", sizeof c, strlen(c));
                                                 2         1
                          

                          Dann auch eher so:

                          char c[] = "a";
                          printf("%zu %zu\n", sizeof c, strlen(c));
                          

                          LG,
                          CK

                          1. Hi Christian,

                            abgesehen davon, dass %d die falsche Formatangabe für size_t ist!

                            Nein, es ist der richtige. Es fehlt nur der length modifier z:

                            Length modifier

                            Here, "integer conversion" stands for d, i, o, u, x, or X conversion. […]

                            • z A following integer conversion corresponds to a size_t or ssize_t argument, or a following n conversion corresponds to a pointer to a size_t argument.

                            Das richtige Format für size_t ist "%zd" (bzw "%zx" wenn der Wert hexadezimal dargestellt werden soll).

                            Wie oft soll man dir das eigentlich noch erklären, bis du mal einen size_t hast, der $$\ge 2^{31}$$ ist?!

                            Ja, der length modifier z sollte wirklich nicht fehlen.

                            vielen Dank für den Hinweis. Warum beschweren sich die Compiler hier eigentlich eher über ein fehlendes l anstatt gleich auf z hinzuweisen? Die Parameter für printf & Co werden doch mittlerweile standardmäßig geprüft.

                            Viele Grüße
                            Robert

                            1. Hallo Robert,

                              Warum beschweren sich die Compiler hier eigentlich eher über ein fehlendes l anstatt gleich auf z hinzuweisen?

                              Das frage ich mich auch schon länger… meine Vermutung: error messages are hard, let's go shopping. Ich rate hier nur, aber ich denke, dass sie es nicht hinbekommen den Format Typecheck vor der Auflösung von size_t zu unsigned long zu machen.

                              Die Parameter für printf & Co werden doch mittlerweile standardmäßig geprüft.

                              Ja. Die Frage ist nur: wann?

                              LG,
                              CK

                          2. Hallo Christian,

                            das %d kam von mir...

                            Aber ein Längenmodifikator für size_t Argumente? Habe ich noch nie gehört. Muss seit C99 hinzugekommen sein, meine Kenntnisse sind noch auf dem Stand von ANSI C (C89)...

                            Rolf

                            --
                            sumpsi - posui - clusi
                            1. Moin Rolf,

                              Aber ein Längenmodifikator für size_t Argumente? Habe ich noch nie gehört. Muss seit C99 hinzugekommen sein, meine Kenntnisse sind noch auf dem Stand von ANSI C (C89)...

                              Die Sinnhaftigkeit dessen hat Christian ja schon auf den Punkt gebracht: Die Größe eines size_t ist plattformabhängig. Und ja, z ist (neben ll) mit C99 dazugekommen, siehe https://en.cppreference.com/w/c/io/fprintf.

                              Viele Grüße
                              Robert

                            2. Hallo Rolf,

                              Aber ein Längenmodifikator für size_t Argumente? Habe ich noch nie gehört. Muss seit C99 hinzugekommen sein, meine Kenntnisse sind noch auf dem Stand von ANSI C (C89)...

                              Ja, das ist seit C99 spezifiziert und hat vorher als Compiler-spezifische Erweiterung im zumindest GCC sein Dasein gefristet 😉

                              LG,
                              CK

                        2. size_t verstehe ich nicht. Was ist das? Die Länge einer Binary ist es jedenfalls nicht, denn darunter verstehen wir die Anzahl der Bytes und zwar plattformübergreifend und unabhängig von der Rechnerarchitektur.

                          MfG

                          1. Moin,

                            size_t verstehe ich nicht. Was ist das? Die Länge einer Binary ist es jedenfalls nicht, denn darunter verstehen wir die Anzahl der Bytes und zwar plattformübergreifend und unabhängig von der Rechnerarchitektur.

                            etwas, was ich dir schon erklärt habe.

                            Viele Grüße
                            Robert

                            1. Moin,

                              size_t verstehe ich nicht. Was ist das? Die Länge einer Binary ist es jedenfalls nicht, denn darunter verstehen wir die Anzahl der Bytes und zwar plattformübergreifend und unabhängig von der Rechnerarchitektur.

                              etwas, was ich dir schon erklärt habe.

                              Nun, die Länge einer Datei ist plattformunabhängig. Die kann ich mit C bytegenau in den Hauptspeicher legen und brauche dafür einen Speicherbereich mit exakt derselben Länge wie die Binary hat. Beim Lesen in Schritten von n Bytes gilt sinnegmäß dasselbe.

                              Das gilt auch fürs Lesen von Binaries aus einem Socket. Wobei ein Socket nach winsock.h offensichtlich am Stück ausgelesen werden will im Gegensatz zu Perl wo ich das in Chunks (Schritte in n Bytes, n beliebig) direkt übers Handle tun kann.

                              Ergo iteriere ich in C eben über die Binary die im Hauptspeicher liegt. Und auch da ist ein Byte ein Byte und was size_t dazu sagt ist uninteressant solange die Binary von einem Nameserver kommt.

                              MfG

                              PS: Ich bin nicht der Einzige den size_t irritiert.

                              1. Hallo pl,

                                Nun, die Länge einer Datei ist plattformunabhängig.

                                Die maximale Länge einer Datei ist stark abhängig vor der Plattform. Der maximal adressierbare Speicher ist sehr stark abhängig von der Plattform.

                                Und auch da ist ein Byte ein Byte und was size_t dazu sagt ist uninteressant solange die Binary von einem Nameserver kommt.

                                Ob du size_t verwendest oder int ist sehr wohl wichtig. Wenn dir eine Funktion size_t zurück gibt, dann ist das plattformabhängig, wie der Wert interpretiert werden muss. Häufig ist es ein unsigned long, wenn du den jetzt als int interpretierst, dann hast du bei Werten jenseits von INT_MAX Bullshit stehen (nämlich einen negativen Wert durch den Überlauf). Benutze konsequent size_t, wo die Bibliotheken es zurückgeben oder erwarten! Du ersparst dir eine Menge Schmerzen.

                                LG,
                                CK

                                1. Mir gehts um plattformübergreifende Anwendungen und siehe da:

                                  recv - receive a message from a connected socket.. Upon successful completion, recv() shall return the length of the message in bytes.

                                  Alles Andere würde auch gar keinen Sinn ergeben!

                                  1. Hallo pl,

                                    Mir gehts um plattformübergreifende Anwendungen und siehe da:

                                    recv - receive a message from a connected socket.. Upon successful completion, recv() shall return the length of the message in bytes.

                                    Alles Andere würde auch gar keinen Sinn ergeben!

                                    Verwechsele nicht Datentyp und Bedeutung. recv hat folgenden Prototyp:

                                    ssize_t
                                    recv(int socket, void *buffer, size_t length, int flags);
                                    

                                    Daran solltest du dich halten, aus beschriebenen Gründen. ssize_t ist nicht size_t ist nicht int. Wenn dem so wäre, hätte man den Datentyp gar nicht erst eingeführt.

                                    LG,
                                    CK

                                  2. Moin pl,

                                    Mir gehts um plattformübergreifende Anwendungen und siehe da:

                                    recv - receive a message from a connected socket.. Upon successful completion, recv() shall return the length of the message in bytes.

                                    Und für die Länge von etwas gibt es in C die passenden Datentypen, nämlich size_t bzw. ssize_t.

                                    Viele Grüße
                                    Robert

                                    1. Und für die Länge von etwas gibt es in C die passenden Datentypen, nämlich size_t bzw. ssize_t.

                                      Natürlich. Cast'n soll ja auch Spaß machen 😉

                                      Und womer schon dabei sind: Ein DNS Header besteht aus 6 16-Bit-Integer unsigned in Network Order. Ein Struct bietet sich an. Es ist nur so, daß die Endianness eines uint16_t plattformabhängig ist, auf meiner Kiste Little Endian.

                                      Wie könnte denn ein plattformunabhängiges struct diesbezüglich aussehen? 12 members als unsigned char?

                                      MfG

                                      1. Moin,

                                        Und womer schon dabei sind: Ein DNS Header besteht aus 6 16-Bit-Integer unsigned in Network Order. Ein Struct bietet sich an. Es ist nur so, daß die Endianness eines uint16_t plattformabhängig ist, auf meiner Kiste Little Endian.

                                        die Lösung steht im anderen Thread.

                                        Viele Grüße
                                        Robert

                                      2. Hallo pl,

                                        die struct sollte nicht plattformunabhängig sein, nur ihre Übertragung ins Netz. Definiere den DNS Haader als neutralen Container, z.B. so:

                                        typedef struct {
                                            uint16_t id;
                                            uint16_t qr     : 1;
                                            uint16_t opcode : 4;
                                            uint16_t aa     : 1;
                                            uint16_t tc     : 1;
                                            uint16_t rd     : 1;
                                            uint16_t ra     : 1;
                                            uint16_t z      : 3;
                                            uint16_t rcode  : 4;
                                            uint16_t qdcount;
                                            uint16_t ancount;
                                            uint16_t nscount;
                                            uint16_t arcount;
                                        } DNS_HEADER;
                                        

                                        und schreibe eine Funktion sendDNSHeader(uint8_t* outputbuffer, DNS_HEADER* h), die die entsprechenden compile- oder runtime-Abfragen enthält, um die Endianness zu bestimmen, die Flags korrekt zu packen (das ist nicht trivial, wie Bitfelder auf int abgebildet werden ist komplett compilerabhängig) und die 12 Headerbytes in network order in den Outputbuffer zu schreiben.

                                        Viele Compiler schreiben das erste Bitfield in die niederwertigsten Bits des Container-Int. Wenn Du also speziell für einen Compiler programmierst, der das so macht, könntest Du eine struct definieren die die Bitfelder enthält, müsstest dann nur mit rcode beginnen und mit qr aufhören. Das macht die Arbeit etwas leichter. Diesen Code darfst Du dann aber niemandem geben, der ggf. einen anderen Compiler nutzt. Oder Du musst ein Testprogramm mitliefern, dass die Rahmenbedingungen für den Compiler validiert.

                                        Rolf

                                        --
                                        sumpsi - posui - clusi
                          2. Hallo pl,

                            size_t verstehe ich nicht. Was ist das? Die Länge einer Binary ist es jedenfalls nicht, denn darunter verstehen wir die Anzahl der Bytes und zwar plattformübergreifend und unabhängig von der Rechnerarchitektur.

                            size_t ist der Datentyp, mit dem die Größe eines Objektes beschrieben wird (Quelle: C99-Standard):

                            This type is used to represent the size of an object. Library functions that take or return sizes expect them to be of type or have the return type of size_t. Further, the most frequently used compiler-based operator sizeof should evaluate to a constant value that is compatible with size_t.

                            Es ist eine Vereinfachung, um plattformübergreifenden Code zu schreiben. Bei size_t ist gewährleistet, dass du bei Größenangaben nicht in Wertebereiche läufst, die deine Plattform, auf der du den Code entwickelt hast, nicht benutzt hat. Etwa wenn du auf einer 32-Bit-Maschine entwickelst, aber auf einer 64-Bit-Maschine für das Produktiv-System kompilierst.

                            LG,
                            CK

              3. Hallo TS,

                die folgenden Deklarationen / Initialisierungen sind allesamt gleichwertig:

                char bin1[] = { 0, 0, 0, 0 };             // Dezimale Integerwerte für das char-Array
                char bin2[] = { 00, 00, 00, 00 };         // Dito, oktal
                char bin3[] = { 0x00, 0x00, 0x00, 0x00 }; // Dito, hexadezimal
                char bin4[] = "\0\0\0";                   // String mit 3 Nullbytes in oktaler Escape-Sequenz
                char bin5[] = "\x00\x00\x00";             // String mit 3 Nullbytes in hex Escape-Sequenz 
                

                Übrigens nicht 4 Escapesequenzen in den Strings, weil C ja von sich aus noch ein Nullbyte anhängt.

                Rolf

                --
                sumpsi - posui - clusi
                1. Hello,

                  und noch ein wenig mehr zur Verwirrung bezüglich Bytes und Characters in ANSI-C

                  Man muss also schon genau überlegen, wie man die Funktionbeschreibung zu verstehen hat.

                  Glück Auf
                  Tom vom Berg

                  --
                  Es gibt nichts Gutes, außer man tut es!
                  Das Leben selbst ist der Sinn.
                  1. Hallo TS,

                    Rheinwerk erweckt den Eindruck, dass es definierte Längen für die diversen Integer-Typen gäbe. Aber das ist nicht der Fall.

                    Ich habe gerade die Quelle nicht zur Hand, aber die engl. Wikipedia schreibt:

                    The relation requirements are that the long long is not smaller than long, which is not smaller than int, which is not smaller than short. As char's size is always the minimum supported data type, no other data types (except bit-fields) can be smaller.

                    The minimum size for char is 8 bits, the minimum size for short and int is 16 bits, for long it is 32 bits and long long must contain at least 64 bits.

                    The type int should be the integer type that the target processor is most efficiently working with.

                    Also: sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)

                    Niemand verbietet es einem Compiler, sizeof(char)=8 zu verwenden. Aber dann könnte dieser C-Compiler auch nur 8-Byte Brocken als kleinste Einheit verarbeiten.

                    Rolf

                    --
                    sumpsi - posui - clusi
                  2. Hello,

                    und noch ein wenig mehr zur Verwirrung bezüglich Bytes und Characters in ANSI-C

                    Was ist denn daran verwirrend? Wenn Du einmal das Verständnis dafür entwickelt hast was ein Byte ist, dann wird Dir auch klar warum das Internet nur so funktionieren kann, also wenn jeder unter einem Byte dasselbe versteht: Einen Integer im Wertebereich 0..255 (8 Bit)!

                    Nur heißt es eben aufgepasst, daß beim bytesemantischen Programmieren die Bytes nicht negativ werden und daß der Wertebereich eines int von der Rechnerarchitektur abhängt.

                    Wie wärs mit eigenen Typen:

                    #include <stdint.h>
                    typedef uint8_t  Oct; // 1 Byte
                    typedef uint32_t Vax; // Little Endian
                    typedef uint16_t Sho; // Little Endian
                    

                    MfG

                    1. Hello,

                      und noch ein wenig mehr zur Verwirrung bezüglich [Bytes und Characters in ANSI-C](http://openbook.rheinwerk-verlag.de/c_von_a_bis_z/005_c_basisdatentypen_011.htm#mj70d5ed4c4c164bd56bcc13de3d28631

                      Was ist denn daran verwirrend? Wenn Du einmal das Verständnis dafür entwickelt hast was ein Byte ist, dann wird Dir auch klar warum das Internet nur so funktionieren kann, also wenn jeder unter einem Byte dasselbe versteht: Einen Integer im Wertebereich 0..255 (8 Bit)!

                      Das ist eben nicht so, dass ein Byte immer 8 Bits hat! Siehe hierzu auch die Wikipedia

                      Und wenn Du interoperabile [? Begriff] Programme schreiben willst, musst Du das auch beachten. Sonst reißt Du gefährliche Löcher in deine IT-Landschaft.

                      Glück Auf
                      Tom vom Berg

                      --
                      Es gibt nichts Gutes, außer man tut es!
                      Das Leben selbst ist der Sinn.
                      1. Hello,

                        Das ist eben nicht so, dass ein Byte immer 8 Bits hat! Siehe hierzu auch die Wikipedia

                        Wenn das so wäre daß bytes eine unterschiedliche Länge hätten, würde das ganze Internet nicht funktionieren!

                        Siehe DNS und Algorithmen!

                        MfG

                        1. Hello,

                          Das ist eben nicht so, dass ein Byte immer 8 Bits hat! Siehe hierzu auch die Wikipedia

                          Wenn das so wäre daß bytes eine unterschiedliche Länge hätten, würde das ganze Internet nicht funktionieren!

                          Siehe DNS und Algorithmen!

                          Könnte es sein, dass Du den Bytebegriff mit dem des Oktetts verwechselst?

                          Für die Zusammenarbeit (im Internet) ist es nicht relevant, wieviel Bits ein Byte hat, sondern dass die Protokolle der Übertragung/Datenaustausch auf beiden Seiten der Strecke an das jeweilige System andocken können und die übermittelten Daten richtig interpretiert werden können.

                          EMail hat lange Jahre (bis heute) noch mit 7-Bit-Bytes gearbeitet. Die 8-Bit-Version hat sich erst durch die enorme Verbreitung der PC-Systeme und deren Speichermedien mit 8-Bit-Organisation in den Vordergrund gedrängelt, ist aber nichg die allein gültige.

                          Glück Auf
                          Tom vom Berg

                          --
                          Es gibt nichts Gutes, außer man tut es!
                          Das Leben selbst ist der Sinn.
                          1. Hello,

                            Das ist eben nicht so, dass ein Byte immer 8 Bits hat! Siehe hierzu auch die Wikipedia

                            Wenn das so wäre daß bytes eine unterschiedliche Länge hätten, würde das ganze Internet nicht funktionieren!

                            Siehe DNS und Algorithmen!

                            Für die Zusammenarbeit (im Internet) ist es nicht relevant, wieviel Bits ein Byte hat,

                            Doch, genau darauf kommt es an! Ein Nameserver liest nämlich aus der Anfrage genau ein Byte worin steht, wie lang der Domänenname ist, also wieviele Bytes dafür zu lesen sind. Für den Namen example.com in einer Anfrage liest der NS ein Byte und bekommt damit eine 7. Somit liest er 7 Bytes und bekommt example. Dann liest er wieder ein Byte und kriegt eine 3. Damit liest er also 3 Bytes und bekommt com. Das nächste Byte hat die Wertigkeit 0 und das heißt für den NS, daß der Name komplett ist. Es folgen 4 Bytes in welchen Type und Class als Big Endian kodiert sind.

                            Z.B. hat eine MX Abfrage die Nummer 0x000F und Class IN die Nummer 0x0001. Type IN, Class A sind 0x0001 und 0x0001 und damit fragst Du den A-Record ab, da kriegst Du die IP Adresse.

                            Und Letztere besteht, wie soll es anders sein, aus 4 Bytes 😉 IPv4!

                            EMail hat lange Jahre (bis heute) noch mit 7-Bit-Bytes gearbeitet.

                            Du verwechselst Transfer-Encoding mit Bytelength!

                            MfG

                          2. Hallo TS,

                            wichtig ist, dass die Abgrenzungen im übermittelten Datenstrom gleich verstanden werden.

                            Das IP Protokoll definiert die Länge eines IP-Headers in Bits und die Länge des Datagramms in Oktetten. Und RFC-20 legt bereits fest, dass man 7-bit ASCII in 8-bit Oktette einbetten soll.

                            EMail benutzt überhaupt keine Bytes. Nur Zeichen, in einem 7-bit Zeichensatz. Ob ein Zeichen nun in einem Byte, in einem Oktett oder in einem irgendwie gearteten Wort gespeichert werden ist ein Implementierungsdetail.

                            Rolf

                            --
                            sumpsi - posui - clusi
                            1. Ergänzung:

                              Eine Zeichenkodierung ist nur ein Algorihmus der dazu dient, Zeichen auf Byteebene abzubilden und damit transportfähig zu machen.

                              Beispiel UTF-8: Lese das 1. Byte, da steht drin wieviele weitere Bytes zum Zeichen gehören. Lese also diese Bytes und dann wiederholt sich der Vorgang.

                              Andersherum ergibt sich aus dem Codepoint, mit wievielen Bytes das Zeichen zu kodieren ist und welche Wertigkeiten diese Bytes haben.

                              MfG