Forum: Compiler & IDEs Typenkonvertierung


von Klaus M. (meinzinet)


Lesenswert?

Hallo wer kann mir helfen:

Ich möchte eine Funktion aufrufen die einen Parameter mit dem Typ frmt_t 
erwartet, aber übergeben möchte ich den Typ uint8_t (ein Byte)

Beide typen sind genau 1 Byte groß nur eben unterschiedliche Typen
Wie kann ich sowas bewerkstelligen?

also ZB

typedef struct
{
  uint8_t comma   : 2;
  uint8_t rundung : 2;
  uint8_t sign    : 3;
  uint8_t rest    : 1;
} frmt_t;

void var2str(frmt_t varx)
{
  if(varx.comma == 1) ......usw

}

void aufruf(const char *pgmstrg)
{
  uint8_t frmt= pgm_read_byte(pgmstrg
  var2strg(*(frmt_t *)&frmt); // der Aufruf funktioniert
  var2strg(0x10);  // Hier jedoch  error: conversion to non-scalar type 
requested
}

von M. K. (kichi)


Lesenswert?

Hast du es schonmal mit einer zusätzlichen Union versucht? Also ein Char 
und dein Struct innerhalb der Union...

von Luther B. (luther-blissett)


Lesenswert?

Konversionen zwischen skalaren und nicht-skalaren sind ein 
Wartungs-Risiko, weil der skalar eine binär-Repränsentation des 
nicht-skalaren darstellen muss und diese Verknüpfung ziemlich locker in 
einem cast drinsteckt. Wenn du aber trotzdem willst, kannst du diese 
Makros benutzten (gcc-spezifisch):
1
#define static_assert(X) {char __p__[(X)-1];}
2
#define reinterpret(T,V) ({union{T a; typeof(V) b;} __x__; static_assert(sizeof(T)==sizeof(V)); __x__.b=(V); __x__.a; })
3
4
...
5
val2strg(reinterpret(frmt_t,(uint8_t)0x10));

Das static_assert dient dazu sicherzustellen, daß der Wert, denn du an 
reinterpret() übergibst, die gleiche Größe wie der Typ hat in den du 
umwandeln willst (0x10 ist ein int!) und nicht etwas etwas abgeschnitten 
wird.

von Klaus M. (meinzinet)


Lesenswert?

Danke für die Makros

Habs schon ausprobiert, es funktioniert prima!!

Keine Ahnung was die makros genau machen, aber es geht.

static assert versteh ich noch, wird zur compile zeit abgefragt ob die 
Datentypen gleich groß sind.
Nachdem was ich jetzt so nachgeschlagen habe wird durch union erreicht, 
dass beide Datentypen den gleichenspeicherberreich haben.
Nur wie der Compiler das ganze bei einem Funktionaufruf einfach schluckt 
:-( ??

Trotzdem vielen Dank, hat mir sehr geholfen

von M. K. (kichi)


Lesenswert?

Klaus Me wrote:
> Nachdem was ich jetzt so nachgeschlagen habe wird durch union erreicht,
> dass beide Datentypen den gleichenspeicherberreich haben.
> Nur wie der Compiler das ganze bei einem Funktionaufruf einfach schluckt
> :-( ??

Wenn du es richtig machst ist das kein Problem... Du kannst entweder mit 
Zeigern arbeiten oder direkt eine der Komponenten übergeben - je nachdem 
was dir lieber ist.

Typenkonvertierung ist eine der Hauptanwendungen von Unions.

von Rolf Magnus (Gast)


Lesenswert?

> Typenkonvertierung ist eine der Hauptanwendungen von Unions.

Eigentlich nicht. Sie werden nur sehr häufig dazu mißbraucht. Für 
Typkonvertierungen sind eigentlich die Casts da.

von Luther B. (luther-blissett)


Lesenswert?

Klaus Me wrote:

> Keine Ahnung was die makros genau machen, aber es geht.

GCC hat ein paar Erweiterungen, die einem definitiv das Leben leichter 
machen. Für details:

http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Statement-Exprs.html
http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Typeof.html

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.