Precompiler



  • Hallo,

    ich habe folgende Angabe gemacht

    #if (0xFF > 0x0ffffffffL)

    Diese Angabe ist "true". Warum?
    Mein Compiler ist der C51 von KEIL

    Grüßle
    Fahrenheit



  • `

    0x0ffffffffL mal etwas breiter geschrieben: 0x0 ff ff ff ff L Es ist also eine long, bei der 32Bit gesetzt sind. Das ist im Zweierkomplement aber -1. Das 0xff wird zu 0x000000ff -> 255. Dann steht da #if (255 > -1)`
    Warum das true ist, sollte klar sein.



  • ok... verstanden

    und warum ist dann der folgende Ausdruck "false"?

    #if (0xFFU > 0x0ffffffffL)



  • DirkB schrieb:

    `

    0x0ffffffffL ` mal etwas breiter geschrieben: 0x0 ff ff ff ff L
    Es ist also eine long, bei der 32Bit gesetzt sind. Das ist im Zweierkomplement aber -1.

    Laut Standard hat dieses Literal aber den Typ unsigned long int . OK, das ist der C99-Standard (siehe Tabelle in 6.4.4.1), vielleicht war es in C89 noch anders (glaub ich aber ehrlich gesagt nicht.) Ich tipp mal auf Compiler-BugEigenheit.


  • Mod

    Bashar schrieb:

    DirkB schrieb:

    `

    0x0ffffffffL ` mal etwas breiter geschrieben: 0x0 ff ff ff ff L
    Es ist also eine long, bei der 32Bit gesetzt sind. Das ist im Zweierkomplement aber -1.

    Laut Standard hat dieses Literal aber den Typ unsigned long int . OK, das ist der C99-Standard (siehe Tabelle in 6.4.4.1), vielleicht war es in C89 noch anders (glaub ich aber ehrlich gesagt nicht.) Ich tipp mal auf Compiler-BugEigenheit.

    Ich bin mir nicht so sicher, dass aus der Tabelle zwangsläufig unsigned folgt:

    If an integer constant cannot be represented by any type in its list, it may have an
    extended integer type, if the extended integer type can represent its value. If all of the
    types in the list for the constant are signed, the extended integer type shall be signed. If
    all of the types in the list for the constant are unsigned, the extended integer type shall be
    unsigned. If the list contains both signed and unsigned types, the extended integer type
    may be signed or unsigned.

    Hier haben wir doch den letzten Fall vorliegen.



  • Der extended integer type kommt doch nur zum Tragen, wenn die Konstante durch keinen der Typen in der Liste dargestellt werden kann: «If an integer constant cannot be represented by any type in its list, it may have an
    extended integer type»


  • Mod

    Bashar schrieb:

    Der extended integer type kommt doch nur zum Tragen, wenn die Konstante durch keinen der Typen in der Liste dargestellt werden kann: «If an integer constant cannot be represented by any type in its list, it may have an
    extended integer type»

    Genau der Fall liegt doch vermutlich vor. 0x0ffffffff kann größer sein als INT_MAX_LONG, welches laut Standard nur (0x80000000 - 1) sein braucht. Bei einem Microcontrollercompiler kann ich mir schon gut vorstellen, dass nur die Mindestgröße unterstützt wird.



  • Nun ja, der C51 ist ein Compiler für den 8051 µC.

    Der hat ein paar Einschränkungen und auch Erweiterungen.
    Ein integer-Datentyp von mehr als 32 Bit kennt der (soweit ich das gesehen habe) nicht.
    Also bleiben nur die 32 gesetzten Bit, und der User hat mit L einen signed Typ gewünscht.

    Fahrenheit500 schrieb:

    und warum ist dann der folgende Ausdruck "false"?

    #if (0xFFU > 0x0ffffffffL)

    Beim ersten Beispiel wurden signed Zahlen verglichen.
    Hier hast du jetzt signed und unsigned.
    Da kommen wieder Umwandlungen zum tragen (die ich jetzt nicht kenne), die evtl aber auch in der Limitierung der Datentypen vom C51 liegen.



  • SeppJ schrieb:

    Bashar schrieb:

    Der extended integer type kommt doch nur zum Tragen, wenn die Konstante durch keinen der Typen in der Liste dargestellt werden kann: «If an integer constant cannot be represented by any type in its list, it may have an
    extended integer type»

    Genau der Fall liegt doch vermutlich vor. 0x0ffffffff kann größer sein als INT_MAX_LONG

    Aber nicht größer als ULONG_MAX (mindestens 4294967295 = 232-1). Ich zitiere nochmal den Standard:

    6.4.4.1 Integer constants

    5 The type of an integer constant is the first of the corresponding list in which its value can be represented.

    [Tabelleneintrag für Suffix l oder L und für oktale oder hexadezimale Konstanten:]

    long int
    unsigned long int
    long long int
    unsigned long long int

    Da die Konstante 0xFFFFFFFFL nicht in long int passt, aber in unsigned long int schon, muss sie letzteren Typ haben.

    DirkB schrieb:

    Also bleiben nur die 32 gesetzten Bit, und der User hat mit L einen signed Typ gewünscht.

    Das ist es doch gerade, was ich sage: L bedeutet nicht, dass es ein signed-Typ ist. Das ist nur für dezimale Konstanten so. Oktale und hexadezimale Konstanten mit L können auch einen unsigned-Typ haben.

    Habs jetzt übrigens gecheckt, das ist auch in C89 so (ohne long long selbstverständlich.)

    Nochmal edit: In C89 war es sogar so, dass dezimale Konstanten ohne Suffix oder mit L unsigned-Typen haben konnten (nämlich (int ->) long int -> unsigned long int). Das hat sich geändert.


Anmelden zum Antworten