Forum: Compiler & IDEs 2 int8 in ein int16 reinkopieren?


von neumann (Gast)


Lesenswert?

Hallo,

wie kann man am Besten 2 8Bit Variablen in eine 16Bit Variable kopieren?

Durch Schiebeoperationen?

Das muss doch auch effizienter gehen?

Gruß Bernd

von Naja...Schüler (Gast)


Lesenswert?

neumann schrieb:
> Das muss doch auch effizienter gehen?

Effizienter als Schieben und oder Verknüpfung/Zuweisung?
Wohl kaum!

von Noname (Gast)


Lesenswert?

Wenn Du mehr tust, als die Behauptung

>Das muss doch auch effizienter gehen...

in den Raum zu stellen, könnte man ja mal darüber nachdenken.

Ansonsten würde ich Dir das umgekehrte Verfahren empfehlen.
Implementiere es, schau Dir den Assemblercode an
und denk nochmal d'rüber nach.

von LittleBigEndian (Gast)


Lesenswert?

Ja, das geht definitiv effizienter:
Variablen im Speicher hintereinander ablegen ;)

von stdint (Gast)


Lesenswert?

#include <stdint.h>

...

uint8_t var1 = 0x12;
uint8_t var2 = 0x34;

uint16_t var3 = (var1 << 8) | var2;

von Matthias L. (Gast)


Lesenswert?

>uint16_t var3 = (var1 << 8) | var2;

Ich vermute mal, das hier nur der Wert von var2 in var3 stehen wird.

von Floh (Gast)


Lesenswert?

Was erwartest du denn für ein Verhalten, wenn du zwei 
VORZEICHENBEHAFTETE 8-Bit Werte in einen 16bit Wert verwandelst?

von Stefan E. (sternst)


Lesenswert?

Matthias Lipinsky schrieb:
>>uint16_t var3 = (var1 << 8) | var2;
>
> Ich vermute mal, das hier nur der Wert von var2 in var3 stehen wird.

Nein. (Integer-Promotion!)

von Stefan E. (sternst)


Lesenswert?

Floh schrieb:
> Was erwartest du denn für ein Verhalten, wenn du zwei
> VORZEICHENBEHAFTETE 8-Bit Werte in einen 16bit Wert verwandelst?

Und wo bitte siehst du in diesem Thread "VORZEICHENBEHAFTETE 8-Bit 
Werte"?

von Floh (Gast)


Lesenswert?

Ich beziehe mich auf den Threadtitel :-)
"2 int8 in ein int16"

von Mike (Gast)


Lesenswert?

Wie wärs mit einer union aus int und einem Array aus 2x int8?

von Stefan E. (sternst)


Lesenswert?

Floh schrieb:
> Ich beziehe mich auf den Threadtitel :-)
> "2 int8 in ein int16"

Ups.
Ach na ja, wer achtet denn schon auf den Titel. ;-)

von Der Neue (Gast)


Lesenswert?

Mike schrieb:
> Wie wärs mit einer union aus int und einem Array aus 2x int8?

Wenn man recht schaut wird da auch nichts anderes dabei rauskommen als 
ein Casting, Verschieben und Zuweisen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Bei der Union ist das Ergebnis nicht portabel, ist also mithin von 
verwendeter Plattform und Compiler abhängig (ein avr-gcc ist was anderes 
als ein arm-gcc).

Auch denn in einem speziellen Fall eine Union ein paar Instruktionen 
sparen sollte, ist die portable und lesbare Variante vorzuziehen.

Den Code mit Casts zu Union und/oder Type-Punning zu verunstalten um ein 
paar Assembler-Instruktionen rauszuhacken ist nicht wirklich eine gute 
Idee.

In der portablen C99 Variante
1
#include <stdint.h>
2
3
uint16_t glue (uint8_t lo, uint8_t hi)
4
{
5
    return (hi << 8) | lo;
6
}
Gibe es 5 Operationen: Ein Shift, ein Or, zwei 8->16 Promotions und eine 
16-Bit Zuweisung.

GCC verliert hier leider gerne den Überblick über das Gesamtbild, das 
sich dem Assembler-affinen Programmierer als 2 8-Bit Zuweisungen 
darstellt, die bei geschickter Umsetzung des umgebenden Codes sogar 
entfallen können.

Diese Diskrepanz ist es, welche "erfahrene" Entwickler zu Union-Hacks 
greifen lässt. Aber führt man das Szenario konsequent fort, frogrammiert 
man Assembler in C und hackt sich hinter jeder verlorenen Instruktion 
her...

Dann sieht der Code irgendwann aus wie Sauerkraut, obwohl die Ursache 
zwo Assembler-Instruktionen von einer Compiler-Version waren, die schon 
seit Jahren nicht mehr eingesetzt wird. Und keiner rafft's mehr. Weder 
was wirklich im Code passiert, nach warum es genau so passiert.

Und Ja, das Problem ist im GCC bekannt: PR41076. Und ja, auch 
GCC-Entwickler wissen wie guter Code auszusehen hat und sind nicht 
komplett doof ;-)

von Der Neue (Gast)


Lesenswert?

Wäre es dann Sinnvoll die oben genannte "Funktion" als Inline zu 
deklarieren?
Dann würde man sich doch die Funktionseinprünge sparen, oder?

Gruß

von Rolf M. (rmagnus)


Lesenswert?

Ja, bei so kurzen Funktionen ist das durchaus sinnvoll.

von Andreas B. (andreas_b77)


Lesenswert?

Wobei "inline" ja auch nur eine Empfehlung ist und vom Compiler nicht 
zwangsläufig befolgt wird. Umgekehrt kann der Compiler auch automatisch 
eine Funktion inline expandieren, wenn es dem Optimizer sinnvoll 
erscheint. Bei einer derart kurzen und einfachen Funktion kann man 
eigentlich drauf wetten.

von LittleBigEndian (Gast)


Lesenswert?

Johann L. schrieb:
> Bei der Union ist das Ergebnis nicht portabel, ist also mithin von
> verwendeter Plattform und Compiler abhängig (ein avr-gcc ist was anderes
> als ein arm-gcc).

Das stimmt so nicht.

von Rolf M. (rmagnus)


Lesenswert?

LittleBigEndian schrieb:
> Johann L. schrieb:
>> Bei der Union ist das Ergebnis nicht portabel, ist also mithin von
>> verwendeter Plattform und Compiler abhängig (ein avr-gcc ist was anderes
>> als ein arm-gcc).
>
> Das stimmt so nicht.

Doch, das stimmt. Und wenn man es streng nach ISO C sieht, geht es sogar 
noch einen Schritt weiter: Da ist nicht einmal definiert, was überhaupt 
passiert, wenn du solche Schweinereien versuchst.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.