Verwirrung um Datentypen oder: Warum klappt das so nicht?

  • Hallo,


    ich möchte mehrere Werte (davon auch welche dezimal negativ) einlesen (in dem Fall sind beide jeweils ein Byte) und diese zusammenhängend als 16 Bit schreiben bzw erstmal nur ausgeben, das Schreiben erfolgt woanders und klappt auch. Der gesamte Code der jetzt kommt, funktioniert tadellos.



    Ausgabe aufm Schirm:

    Code
    Register HSC - Horizontal Scaling Coefficients, 0x08, 2 Byte
    HDSC Wert dezimal (-63 bis 0): -12
    HUSC Wert dezimal (0 bis 127): 12
    0x0cf4


    Also alles wie gewünscht: -12 sind F4 und 12 sind 0C.
    Der Code kompiliert auch ohne Warnungen.
    Aber warum klappt folgendes NICHT?:


    Code
    int8_t hdsc, husc;


    Der Compiler gibt folgende Warnungen:

    Code
    writefocus.c: In function `write_HSC':
    writefocus.c:96: warning: int format, different type arg (arg 2)
    writefocus.c:104: warning: int format, different type arg (arg 2)
    writefocus.c:106: warning: comparison is always true due to limited range of dat
    a type


    Raus kommt dann das:

    Code
    Register HSC - Horizontal Scaling Coefficients, 0x08, 2 Byte
    HDSC Wert dezimal (-63 bis 0): -12
    HUSC Wert dezimal (0 bis 127): 12
    0x0c00


    Warum wird F4 dort zu 00?
    Und warum beschwert sich der Compiler überhaupt? mit int gehts, mit int8_t nicht, dabei gibts da doch keinen Wert, der da nich reinpassen würde. Ausserdem scheint das mit dem if durchaus zu funktionieren.
    Tipp ich -64 ein oder 128 kommt die Abfrage - wie gewünscht - erneut.


    Wäre nett, wenn mir das jemand erklären könnte. Momentan isses mir völlig unverständlich, warum int8_t nicht tut.

  • Hab zwar schon länger kein c mehr programmiert aber das zauberwort heisst wohl casting...


    Du liest ein int (16bit oder 32bit) ein und versuchst dies ohne typumwandlung in ein int8 (8bit?) zu schreiben.
    Und mit "different type arg" versucht dir das der compiler auch mitzuteilen...

  • ich caste doch beim aufruf der funktion? Ausserdem erwartet die getbits funktion uint32_t, was ein normales int definitiv auch nicht ist, das is nämlich signed.


    Dies scheint auch zu klappen, da ich z.b. -12 bei nem int als 0xFFFFFFF4 im Speicher hätte, durch (uint8_t) isses nur noch F4.

  • Code
    uint32_t setreg(uint32_t upper, uint32_t ustart, uint32_t lower) {
    	uint32_t data = (upper << ustart) | lower;
    	return data;
    }


    Deine Funktion frisst aber uint32_t, du castest im Funktionsaufruf auf uint8_t....

    This is a .44 Magnum, the most powerful handgun in the world. It can take your head clean off. You've got to ask yourself one question, Do I feel lucky?
    easyvdr 0.9a2 - TT-DVB-S2-6400 - ASUS AT3IONT-I deluxe - Atom 330 - 1,5TB WD EADS - Denon 1910 - Toshiba 42X3030D - Harmony 700

  • das geht aber ohne probleme, auch ohne Warnung. Das Casten auf uint8_t tu ich, um 0xF4 zu kriegen. Caste ich das mit -12 auf uint32_t, habe ich 0xFFFFFFF4. Die Warnung und das problem kommt ja erst, wenn hdsc und usch int8_t sind, bei int gehts.

  • Naja, bei scanf("%i", &hdsc); könnte ja schon was schief gehen wenn hdsc kein int mehr ist.
    Eine Ausgabe was genau eingelesen wurde wär evtl. ganz nett...
    Man sieht ja so nur die Eingabe von scanf und nicht den Wert der in hdsc steht, bzw. nur die Ausgabe nach setreg.

  • Zitat

    Original von devzero
    Und warum beschwert sich der Compiler überhaupt? mit int gehts, mit int8_t nicht, dabei gibts da doch keinen Wert, der da nich reinpassen würde.


    Du musst dem Compiler bzw. Scanf auch mitteilen das Du da nur ein int8 einlesen willst. Du rufst scanf mit "%d" als Parameter auf, das impliziert das Du ein int einlesen willst. Wenn Du nur eine 8-Bit Variable hast, versuchs mal mit nem modifier also z.B so: scanf("%hhd",&hdsc) ;

  • Denn das %i dürften halt 16 oder 32 bit sein, die dann in eine 8bit variable geschrieben werden.
    Damit könnte dann auch direkt die Speicherzelle daneben mit überschrieben werden...
    Und solange Du nicht aus dem zugewiesenen Speicherblock rauskommst meldet das Betriebssystem keinen Speicherzugriffsfehler...
    Dafür ist man unter c halt selbst verantwortlich...

  • Der Compiler beschwert sich übers falsche casting, ist jedoch nicht schlimm da Du ne kleinere in ne grössere Variable schreibst...


    Bei dem scanf schreibst Du ne grössere in ne kleinere und durch die "pointeroperation" meckert der compiler nicht...
    Du sagst quasi nur 32bit an diese Stelle, das an der Stelle aber nur 8bit vorgesehen sind fällt dem Compiler nicht auf und zur Laufzeit werden dann halt die vollen 32bit geschrieben und damit halt wohl auch die anderen 24bit neben der Variable.


    (mit der Fehlermeldung hab ich mich da wohl am anfang vertan...)

  • Zitat

    Wäre nett, wenn mir das jemand erklären könnte. Momentan isses mir völlig unverständlich, warum int8_t nicht tut.


    der 'scanf("%i", &hdsc);' schreibt immer in 32 Bit. Wenn du dem nun stattdessen die Adressen von 8 Bit Variablen 'int8_t ' gibst, ueberschreiben sich die Werte der beiden Variablen im Speicher. Das geht u.U. gut solange du innerhalb der Schleifen bist. Aber zum Zeitpunkt wenn er in der 2. Schleife ist, wurde der Wert von 'hdsc' bereits vermanscht.


    ach ich lese gerade die Frage wurde ja schon beantwortet :lol2

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!