[C++] For schleife in Makro

Gast #3893207
Lesenswert?

Hallo zusammen,

ich würde mir gerne Code automatisch vom Präprozessor generieren lassen.
Folgendes Problem.
Es sind folgende Variablen vorhanden.
1
 
2
  int var0;
3
  int var1;
4
  int var2;
5
  int var3;
6
  int var4;
Die Anzahl der Variablen wird von einem anderen Code-Generator erzeugt 
und sind fortlaufend numeriert.

Ich kenne die maximale Anzahl der Variablen
1
#define MAX_VAR 5

Um die Variablen im Programm leichter anzusprechen würde ich die Pointer 
gerne in ein Array schieben.
1
int* vars[MAX_VAR]

Es ist etwas umständlich das von Hand zu machen in der Art
1
vars[0] = &var0;
2
vars[1] = &var1;
3
vars[2] = &var2;
4
vars[3] = &var3;
5
vars[4] = &var4;

Da sich die Anzahl der Variablen ändern kann, wäre es schön, wenn ich 
nur das define MAX_VAR ändern bräuchte und die Zuweisungen werden 
automatisch generiert.

Kann man das über Makros lösen?

Also ein Makro wie
1
#define GENERATE_ALL_ASSIGNMENTS(i)
2

3
GENERATE_ALL_ASSIGNMENTS(MAX_VAR)

Einen ersten Schritt hab ich schon
1
#define GENERATE_ASSIGNMENT(i) vars(i) = &var ## i

Jetzt fehlt "nur" eine Präprozessor Schleife darum, die das mit 
unterschiedlichen Parameter aufruft.

Vielen Dank
Gast #3893249
Lesenswert?

Rufus Τ. Firefly schrieb:
> icke schrieb:
>> Die Anzahl der Variablen wird von einem anderen Code-Generator erzeugt
>> und sind fortlaufend numeriert.
>
> Das Konzept ist kaputt. Lässt sich das vielleicht gleich an der Quelle
> beheben?

Leider nicht...
Die Variablen werden von einem SimulationsFramework aus einer ICD heraus 
generiert.
Ich kann leider erst an der Stelle ansetzen, an der die Variablen schon 
vorhanden sind.


Micha schrieb:
> Wie wäre es mit einem Template wenns C++ ist? Müsste einfacher sein.

Wie meinst Du das?
Dann muss ich die Templetes trotzdem händisch mit den VariablenNamen 
füttern.
#3893264
Lesenswert?

icke schrieb:
> Jetzt fehlt "nur" eine Präprozessor Schleife darum, die das mit
> unterschiedlichen Parameter aufruft.

Leider kennt der C Praeprozessor keine Schleifen. Und ein for() loop 
kommt zu spaet, denn dieser wird zur Laufzeit ausgefuehrt, aber die 
Variablennamen braucht man zur Compile-Zeit. Desselbe Problem sollte 
sich mit Templates ergeben.

Die einzige Moeglichkeit die ich sehe ist, selber einen Code-Generator 
zu schreiben. :-(

ZigZeg
#3893279
Lesenswert?

Noch eine Idee:
FALLS (und wirklich nur dann) die variablen var0..var5 lueckenlos im 
Speicher liegen (z.B. weil sie hintereinander definiert werden), kann 
man auch einfach folgendes machen:
1
int *vars = &var0;
2
vars[0] = 1;
3
vars[1] = 42;
4
...
5
vars[MAX_VAR-1] = foo;

Lass Dich aber nicht erwischen, denn sauber ist das nicht !

ZigZeg
#3893317
Lesenswert?

Die sauberste Lösung ist immer noch, sich selbst ein C Programm zu 
schreiben, welches aus dem vom Codegenerator gelieferten die Arrayform 
erzeugt und diese Programm dann in den Build Prozess einzuschleusen.
Mit reinem C gibt es keine saubere Möglichkeit, die nicht auf 
irgendwelchen windigen und ungedeckten Annahmen beruht.
Gast #3893324
Lesenswert?

Boston schrieb:
> Aber machen die nicht auch nur reine Textersetzung?
Nein, eben nicht. Aber genau braucht man hier (wie es eben der 
Präprozessor macht).
> Verhalten sich die nicht ähnlich zum ## Operator des C-Präprocessors?
Nein.

Der C Präprozessor geht schon in die richtige Richtung, ist aber leider 
viel zu eingeschränkt.

Karl Heinz schrieb:
> Die sauberste Lösung ist immer noch, sich selbst ein C Programm zu
> schreiben,
Kein Grund sich für sowas mit C herumzuquälen... Das geht mit ruby, 
Python, m4, ... viel einfacher...
#3893355
Lesenswert?

Boston schrieb:
> Aber machen die nicht auch nur reine Textersetzung?
> Verhalten sich die nicht ähnlich zum ## Operator des C-Präprocessors?

Absolut nicht, Templates sind extrem leistungsfaehig, gerade auch um 
Code ohne function-call Overhead zu generieren. Mit Macors geht das nur 
bis zu einem bestimmten Grad, und wird schnell unuebersichtlich.

Es lohnt sich, sich damit zu beschaeftigen !

ZigZeg
Gast #3893613
Lesenswert?

Gibts eine obere Schranke für MAX_VAR?
Eine einfache Lösung wär eine Datei à la

#if MAX_VAR>0
vars[0] = &var0;
#endif

#if MAX_VAR>1
vars[1] = &var1;
#endif

...

#if MAX_VAR>999
vars[999] = &var999;
#endif

#if MAY_VAR>1000
#error "More copy & paste needed! :) "
#endif

Sicher noch sauberer, als zu hoffen, dass die Varablen hintereinander im 
Speicher liegen...
Gast #3893920
Lesenswert?

Es gibt eine logische Grenze.
Hab mir jetzt ein kleinss Shell-Script geschrieben, dass einen Header 
erzeugt,den ich mit #include einbinde. Vielleicht erweitere ich das 
Script noch,dass es das #define aus der Datei ausliest und binde es noch 
mit in das Makefile ein.
Persönliche Seite #3894717
Lesenswert?

icke schrieb:
1
>   int var0;
2
>   int var1;
3
>   int var2;
4
>   int var3;
5
>   int var4;
> Die Anzahl der Variablen wird von einem anderen Code-Generator erzeugt
> und sind fortlaufend numeriert.

Lass die Variablen doch einfach als "var[3]" ausgeben anstatt als 
"var3".  Ist doch nur ein anderer String.


Kai S. schrieb:
> FALLS (und wirklich nur dann) die variablen var0..var5 lueckenlos im
> Speicher liegen (z.B. weil sie hintereinander definiert werden),

Dass die Variablen hintereinander definiert werden bedeutet kineswegs 
dass sie auch in der gleichen Reihenfolge oder lückenlos im Speicher 
liegen!
Gast #3894912
Lesenswert?

Johann L. schrieb:
> icke schrieb:
>>   int var0;
>>   int var1;
>>   int var2;
>>   int var3;
>>   int var4;
> Die Anzahl der Variablen wird von einem anderen Code-Generator erzeugt
> und sind fortlaufend numeriert.
>
> Lass die Variablen doch einfach als "var[3]" ausgeben anstatt als
> "var3".  Ist doch nur ein anderer String.

Ich habe keine Möglichkeit,die Variablen zu ändern. Die werden so von 
einem Framework generiert.

Die eigentlichen Variablen sind auch jeweils ein char var[8]. Und das 
Framework unterstütz keine mehrdimensionalen Arrays. Daher die 
var0-varXX Definitionen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren