2 byte in ein 16 bit int

Gast #1535227
Simon schrieb:
> würde eine Union so aussehen?
>
> union u16 { char a; char b;} ;

nein, eher so:

union blah {
    uint16_t als_int;
    struct {
        uint8_t ein_byte;
        uint8_t nochn_byte;
    } als_bytes;
};


union blah test;
test.ein_byte = 0x42;
test.nochn_byte = 0x23;

uint16_t irgend_nen_int = test.als_int;
#1535236
wobei shiften und multiplizieren nicht besonders effizient sind,
wenn es öfter gemacht wird.

Schneller ist die Geschichte mit der union.

Falls es schnell gehen soll und die union zu unpraktisch erscheint,
dann geht es auch so:
1
uint16_t   ergebnis;
2
uint8_t    daseinebyte, dasanderebyte;
3
...
4
((uint8_t*)&ergebnis)[0] = daseinebyte;
5
((uint8_t')&ergebnis)[1] = dasanderebyte;
Gast #1535245
Klaus Wachtler schrieb:
> wobei shiften und multiplizieren nicht besonders effizient sind,
> wenn es öfter gemacht wird.
so? shift und oder hat der avr in hardware. das geht auch in 16bit 
schnell.
#1535253
Pete K. schrieb:
> Es ist IMHO nicht garantiert, dass in einer union die Variablen auf
> fortlaufenden Speicheradressen abgebildet werden. Hängt vom Compiler ab.

Die Elemente einer union sind eh nicht auf fortlaufenden Adressen,
höchstens die der struct.
Gast #1535294
Nils S. schrieb:
> i = (byteH << 8) + byteL;
vorsicht, das muss nicht klappen! dein byteH musst du casten, sonst 
schiebst du aus deinem speicherbereich raus.
auf dem avr klappt das vermutlich, weil er bei einem shift um größer 7 
sowieso weiteren speicher braucht und der compiler den bereitstellt.
auf anderen architekturen muss das nicht so ein.
#1535339
Michael M. schrieb:
> Nils S. schrieb:
>> i = (byteH << 8) + byteL;
> vorsicht, das muss nicht klappen! dein byteH musst du casten, sonst
> schiebst du aus deinem speicherbereich raus.

Da wird nach Standard C nichts "rausgeschoben" und muss nichts gecastet 
werden.  Und zwar gleich aus 2 Gründen, die der Standard vorgibt:

- der rechte Operand von << ist ein Integer, also muss das Ergebnis 
mindestens Integer sein

- kleinere Werte als int werden automatisch zu int (integer promotion), 
bevor sie verrechnet werden.  Über die Sinnhaftigkeit dieser Regel kann 
man sich bei so kleinen CPUs lange unterhalten und es gibt gute 
Argumente dagegen.  Ich habe eine gute Ausrede:  Es ist Vorschrift.
Gast #1535364
> Michael M. schrieb
> > Hc Zimmerer schrieb:
> > [ käse]
> sicher nicht auf dem avr-gcc...

Hier sollte eine Quelle angegeben werden, falls der C-Standard von 
avr-gcc an dieser Stelle verletzt wird. Meines Erachtens ist's genauso, 
wie Hc schreibt. An was sollte sich ein C-Compiler denn bei der 
Auswertung von Ausdrücken halten?

Reiner
Gast #1535375
integer (16bit) promotion auf einer 8-bit architektur macht keinen sinn.
und der rechte operad vom shift ist kein int (16 bit integer), sondern 
ein char (8 bit integer).
#1535385
Michael M. schrieb:
> integer (16bit) promotion auf einer 8-bit architektur macht keinen sinn.
> und der rechte operad vom shift ist kein int (16 bit integer), sondern
> ein char (8 bit integer).

[ ] Du hast Ahnung davon, was der C-Standard von einem Compiler fordert
    damit er als C-Compiler gilt
[ ] Du weißt vielleicht nicht, dass C eine Sprachdefinition hat und
    nicht jeder dahergelaufene Compilerbauer seine Sprache so
    implementieren kann wie er möchte und das Ganze dann "C" nennen
    kann.
[ ] Du hast deinen K&R aufmerksam gelesen und festgestellt, dass in
    C zwar manches (vieles) dem Compilerbauer freigestellt ist, es aber
    trotzdem ein paar grundlegende Dinge gibt, an die er sich halten
    muss.
#1535395
Michael M. schrieb:
> integer (16bit) promotion auf einer 8-bit architektur macht keinen sinn.

Nicht alles, was der C-Standard vorschreibt, macht auf allen 
Architekturen Sinn (und ich habe die Sinnhaftigkeit auch erwähnt).  Die 
GCC-Familie inklusive avr-gcc hält sich daran.

> und der rechte operad vom shift ist kein int (16 bit integer), sondern
> ein char (8 bit integer).

Ein Buch über C hilft hier doch sehr, es muss nicht mal der Standard 
sein.  Das Literal "8" ist ein int.
__
(Und immer noch hast Du keinen Beweis geliefert, sondern nur weitere 
Behauptungen.)
Gast #1535397
Simon K. schrieb:
> Michael M. schrieb:
>> integer (16bit) promotion auf einer 8-bit architektur macht keinen sinn.
> Ist aber trotzdem so bei dem AVR-GCC.
warum wird mein code dann größer, wenn ich beim typedef aus meinem 
int8_t ein int mache?
Gast #1535400
Hc Zimmerer schrieb:
>> An was sollte sich ein C-Compiler denn bei der
>> Auswertung von Ausdrücken halten?
>
> Na, an Michael selbstverständlich.
wär mir auch lieber ^^
#1535423
Michael M. schrieb:
> Simon K. schrieb:
>> Michael M. schrieb:
>>> integer (16bit) promotion auf einer 8-bit architektur macht keinen sinn.
>> Ist aber trotzdem so bei dem AVR-GCC.
> warum wird mein code dann größer, wenn ich beim typedef aus meinem
> int8_t ein int mache?

Das kann man erst beantworten, wenn man den Code sieht.
Auch wenn die C-Regeln grundsätzlich die int-Promotion vorsehen, heißt 
das noch lange nicht, dass ein Compiler sie nicht auch wieder rauswerfen 
darf, wenn er beweisen kann, dass sich durch den Wegfall der Promotion 
nach int nichts ändert.
Das heißt aber nicht, dass die int-Promotion grundsätzlich nicht gilt. 
Das heißt nur, dass ein Optimizer die eigentlich vorhandene Promotion 
weglassen kann, weil sie auf das Ergebnis keinen Einfluss hat.

Wenn der Optimizer sich die Sache ansieht und zb. feststellt, dass das 
Ergebnis in einer 8-Bit Variablen gespeichert wird, kann er den Code 
rückwärts verfolgen und alle High-Byte Manipulationen, die der 
eigentliche Compiler eingefügt hat, wieder rauswerfen, weil sie im 
Ergebnis nicht auftauchen.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 16 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.