PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Preprocessor für Variablentypdeklaration nutzen



Skalden
04-12-2006, 14:07
Hallo,

ich würde gerne eine variable Struktur definieren, die abhängig von einem Argument einen Wert bestimmten Types annimmt.

Kurz zur Erläuterung meiner Absicht:
Die extensive (und nicht ganz funktionelle) Version würde folgendermaßen aussehen:


struct mystruct_int {
int variable;
};

struct mystruct_char {
char variable;
};

create_struct(char type){
//if type == int
struct mystruct_int newstruct;
// if type == char
struct mystruct_char *newstruct;
/allokiere Speicher auf den newstruct zeigt
return (newstruct);
}

mynewstructure = create_struct(int);


Ich weiß der obere code ist schrecklich, unvollständig und nicht funktional. Es geht mir auch nur darum ganz knapp darzustellen, worauf ich primär hinaus will: Ich deklariere eine Struktur-Variable, deren Inhaltstyp von einem Argument (int, char, float etc.) abhängt.

Im oberen Beispiel ist vor allem eines zu sehen: Jede Einzelmöglichkeit des Typen ist seperat als struct deklariert und bei Bedarf wird auf den passenden struct zugegriffen.

Und nun zu meiner Frage:
Kann ich die Einzelstrukturen eigentlich in einer globalen variablen Strukturdeklaration zusammenfassen, die durch den preprocessor dann ausgewertet wird? Etwas in der Art wie



struct mystruct {
#TYPE variable;
}


wobei #TYPE vom preprocessor durch den richtigen Typ ersetzt wird?

Gruß

Skalden

anda_skoa
04-12-2006, 15:40
Nein, die Raute brauchst du nur bei der Deklaration des Macros



#define CONTENTTYPE char

struct mystruct_int {
CONTENTTYPE variable;
};


Allerdings geht das vermutlich selbst in C sauberer, mit einer union vielleicht.

In C++ macht das ohnehin keinen Sinn

Ciao,
_

Skalden
05-12-2006, 12:24
Hallo anda_skoa,

vielen Dank für die Antwort. Mit C++ kenne ich mich leider nicht aus aber interessieren würde mich dennoch, warum das in C++ keinen Sinn ergibt bzw. was dort die Alternative wäre. Würde das dann auch für C gelten?

Gruß

Skalden

EDIT:
Eine Sache ist mir übrigens noch nicht ganz klar. In Deinem Beispiel ist CONTENTTYPE ja "char" definiert. Was ich ja aber eigentlich suche ist eine Möglichkeit CONTENTTYPE (um jetzt mal bei dem Namen zu bleiben) variabel zu deklarieren.

a) Wie bekomme ich so etwas mit einer Union denn hin?

b) Gibt es nicht irgendeine elegante Methode einen String in eine Typdeklaration umzuwandeln? So in der Art:
#define CONTENTTYPE(TYPE) TYPE
und anschließend übergebe ich dem Makro einen String "char" oder "int"?

EDIT2:

Ok also wenn ich das richtig sehe wäre folgendes eine Lösung:


#define STRUCT(CONTENTTYPE) struct mystruct {\
CONTENTTYPE var;\
}

STRUCT(int) st;


Damit kann ich über das Makro steuern welchen TYP die Variable st.var beinhaltet. Was aber noch nicht funktioniert ist folgende Erweiterung:



#include <stdlib.h>
#include <stdio.h>

#define STRUCT(CONTENTTYPE) struct mystruct {\
CONTENTTYPE var;\
const char *value_type = CONTENTTYPE;\
}

int main() {

STRUCT(char) st;
st.var = 'a';

printf("Char is %d\n",st.var);

return(EXIT_SUCCESS);
}


Das ergibt folgende Fehlermeldung:



test.c: In function ‘main’:
test.c:11: warning: no semicolon at end of struct or union
test.c:11: error: syntax error before ‘=’ token
test.c: At top level:
test.c:11: warning: data definition has no type or storage class
test.c:12: error: syntax error before ‘.’ token
test.c:14: error: syntax error before string constant
test.c:14: error: conflicting types for ‘printf’
test.c:14: note: a parameter list with an ellipsis can’t match an empty parameter name list declaration
test.c:14: warning: data definition has no type or storage class

RHBaum
05-12-2006, 13:55
Wie bekomme ich so etwas mit einer Union denn hin?


union contentElement
{
int IntVar;
char CharVar;
ULONGLONG UInt64Var;
};

enum contentType
{
TYPE_INT = 1,
TYPE_CHAR,
TYPE_UINT64
// und was man sonst noch so braucht, nicht vergessen auch im union mit reinzubauen
};

struct MyVariant
{
contentType typ;
contentElement value;
};

// benutzen geht dann so ....

MyVariant var;

var.typ = TYPE_CHAR;
var.element.CharVar = 'c';

if(var.typ == TYPE_UINT64)
{
ULONGLONG i = var.element.UInt64Var;
}




ich würde gerne eine variable Struktur definieren, die abhängig von einem Argument einen Wert bestimmten Types annimmt.
die frage ist, wann steht der typ fest ?
zur Laufzeit - (userauswahl, je nach inhalt einer datei) wirst im wirkliche dynamic nicht herumkommen. (siehe das variant beispiel oben)
beim kompilieren - ja kein problem, typedefs und templates are your best friends :-)

ciao ...

Skalden
05-12-2006, 14:36
Der Typ steht zur Zeit des Kompilierens fest! Es geht mir darum für manche häufig verwendete Strukturen, die sich lediglich in dem Typ der gespeicherten Daten unterscheiden eine Art Archetyp-Struktur in einer Bibliothek basteln zu können.

RHBaum
06-12-2006, 11:45
Der Typ steht zur Zeit des Kompilierens fest!
dann bringt dir wirkliche dynamic eigentlich nur nachteile ....


Es geht mir darum für manche häufig verwendete Strukturen, die sich lediglich in dem Typ der gespeicherten Daten unterscheiden eine Art Archetyp-Struktur in einer Bibliothek basteln zu können.
Unter c++ die perfekte Stellenausschreibung fuern Template ....

unter C muesstest dich bisserl anders behelfen ....

- geschachtelte includes .....
ne userdefs.h z.b. wo dein Datentyp geteypedeft wird ....
typedef ULONGLONG UserDataT;
die ist projecktspezifisch und steht im projectverzeichnis ....

und nen header fuer deine kombinierte datenstruktur, die auf die userdef daten zugreift ....

struct DataT
{
UserDataT UserData;
// was sonst noch so kommt ....
}

- bedingte compilierung (wenn dir das mit den includes zu viel kuddelmuddel ist)

#ifdef DATAT_INT
typedef int UserDataT;
#elsif DATAT_ULONGLONG
typedef ULONGLONG UserDataT;
#endif

struct DataT
{
UserDataT UserData;
// was sonst noch so kommt ....
}

ciao ....