Forum: PC-Programmierung Größe von Typ "dynamisch" erkennen?


von Christian H. (christian_h52)


Lesenswert?

Hi!

Ist es möglich, dass man in einer Funktion, die einen Parameter vom Typ 
void* hat, zu erruieren auf was für einen datentyp der übergebene Zeiger 
zeigt?

Als Beispiel: Ich möchte eine Funktion in C schreiben, die mir das Bit 
an einer gewissen Stelle zurückgibt - egal welcher Typ, daher größen 
unabhängig. Um jetzt aber testen zu können, ob nicht schon außerhalb von 
der Variable zugegriffen wird bräuchte ich die genaue Größe.
1
int setBit(void* var, int pos){
2
    //testen ob pos sich in var befindet, dh. ZB bei uint8_t pos < 8
3
4
}

sizeof liefert hier ja immer nur die größe von void* - wie könnte ich je 
nach speziellen Typ herrausfinden wie groß der ist? Bei Char[] könnte 
ich nach '\0' suchen, aber bei den int-Werten (uint8_t, uint16_t, ...)??

von Clown (Gast)


Lesenswert?

Kurz gesagt, nein. Du kommst vermutlich nicht drum herum, mehrere 
Funktionen mit Parametern und passenden Datentypen zu verwenden. Und 
wenn Du keinen C++ compiler verwenden möchtest, wirst Du wohl auch 
unterschiedliche Funktionsnamen verwenden müssen.

Als Hack könntest Du die von Dir vorgeschlagene Funktion um einen 
Längenparameter erweitern. Die rufst Du kann mit Hilfe eines Makros auf, 
welches gleich die Größe der übergebenen Variablen mitliefert.

#define setBit(a,b) do { setBitX(a, b, sizeof(a)); } while(0)

Der Code würde zumindest lesbar bleiben.

von Clown (Gast)


Lesenswert?

Denken hilft, sorry. Die do-while Konstruktion mußt Du in diesem Fall 
weglassen, da der Rückgabewert benötigt wird.

von Christian H. (christian_h52)


Lesenswert?

Die Präprozessoranweisung funktioniert soweit ganz gut, aber wegen dem 
void Pointer bekomme ich immer die warunung
1
 warning: dereferencing ‘void *’ pointer [enabled by default]
2
 error: invalid use of void expression
1
int setBitX(void *p, int pos, int len){
2
  if(pos > len){
3
    return -1;
4
  }
5
  
6
  if( p==NULL ){
7
    return -2;
8
  }
9
  
10
  *p |= 1<<pos; //diese Zeile produziert immer den Fehler
11
  return 0;
12
}

Wie könnte ich den Fehler vermeiden? Sollten die Bit-Operatoren nicht 
auf jedem Datentyp funktionieren? - Waurm dann die invalid use Meldung?

von Clown (Gast)


Lesenswert?

Mit void Zeigern sollte eigentlich nicht gerechnet werden.

   *((long *)p) |= 1<<pos;

Ein cast auf den größten, sinnvollen Datentyp sollte das eigentlich 
lösen. Oder in char Zeigern wandeln und dann auch Bitpositiontn 
(Parameter pos) von mehr als 32 zulassen. Dann muß das Bit jedoch 
geringfügig mühevoller herausgesucht werden.

Wenn die Funktion wirklich nur das gesucht Bit zurückgeben soll, scheint 
ein

   return (*((long *)p) >> pos)&0x1;

vermutlich besser geeignet.

von Christian H. (christian_h52)


Lesenswert?

Danke, du hast mir sehr geholfen!

lg

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.