Hallo,
ich möchte ein C-Makro benutzen um eine Zahl in einen Funktionsnamen
einzufügen. Es existieren folgende Funktionen im code welche ich
nacheinander ausführen möchte:
void function1test();
...
void function10test();
Ich hab mir das folgendermassen gedacht:
#define EXECFUNCTION(wert) (function(wert)test)
int main()
{
int i;
for(i=1;i<=10;i++)
{
EXECFUNCTION(i);
}
return 0;
}
Leider funktioniert das nicht, der Compiler meckert ein ; an, da er
folgendes erwartet:
function(argument);
Ich möchte aber nur die Zahl mit dem wert ersetzen. Geht das überhaupt?
Danke und Gruß!
marco polo schrieb: > #define EXECFUNCTION(wert) (function(wert)test) Probier mal das 'test' durch einen ';' zu ersetzen.
Gast
#3492424
Was soll dieser Unsinn - das geht nicht!!!!!!!! define ist ein Textersetzung, sie kann also NIEMALS mit werten einer scheife einen Funktionsnamen zusammenbauen.
Peter II schrieb: > Was soll dieser Unsinn - das geht nicht!!!!!!!! > > define ist ein Textersetzung, sie kann also NIEMALS mit werten einer > scheife einen Funktionsnamen zusammenbauen. Naja Unsinn würd ich es nicht nennen, aber du hast Recht der Preprozessor macht nur eine Textersetzung. Ich möchte das der Preprozessor mir komfortabel die Funktionen erzeugt: void function1test(); ... void function10test(); Und das mit einem Makro.
Gast
#3492463
marco polo schrieb: > Ich möchte das der > Preprozessor mir komfortabel die Funktionen erzeugt: Das geht nicht. Mach ein Array mit Funktionspointern, iteriere dadurch und rufe die Pointer auf.
Gast
#3492467
marco polo schrieb: > Peter II schrieb: >> Was soll dieser Unsinn - das geht nicht!!!!!!!! > Ich möchte das der > Preprozessor mir komfortabel die Funktionen erzeugt: kann schon sein das du das willst, sinn macht es noch lange nicht. Man müsste das mit einem Array aus funktionspointer lösen, aber wenn du bis jetzt nicht verstanden hast warum es so nicht geht, ist da noch etwas hoch für dich.
Das funktioniert so nur in interpretierten Sprachen wie perl, php etc. Der Preprocessor macht aus deinem Code dies (mit gcc -E testbar):
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
Je nachdem, was Du vorhast, sind Alternativen vielleicht ein Array mit Funktionszeigern, ein Unittesting-Framework für C oder automatische Code-Erzeugung mit einer dafür geeigneten Sprache¹ als Teil des Build-Prozesses.
Peter II schrieb: > marco polo schrieb: >> Peter II schrieb: >>> Was soll dieser Unsinn - das geht nicht!!!!!!!! >> Ich möchte das der >> Preprozessor mir komfortabel die Funktionen erzeugt: > > kann schon sein das du das willst, sinn macht es noch lange nicht. > > Man müsste das mit einem Array aus funktionspointer lösen, aber wenn du > bis jetzt nicht verstanden hast warum es so nicht geht, ist da noch > etwas hoch für dich. Auf solche Antworten kann ich verzichten. Bitte Peter vergnüg dich doch wo anders.
Gute Idee mit den Funktionszeigern, Danke!
Gast
#3492484
marco polo schrieb: > Peter II schrieb: >> marco polo schrieb: >>> Peter II schrieb: >>>> Was soll dieser Unsinn - das geht nicht!!!!!!!! >>> Ich möchte das der >>> Preprozessor mir komfortabel die Funktionen erzeugt: >> >> kann schon sein das du das willst, sinn macht es noch lange nicht. >> >> Man müsste das mit einem Array aus funktionspointer lösen, aber wenn du >> bis jetzt nicht verstanden hast warum es so nicht geht, ist da noch >> etwas hoch für dich. > > Auf solche Antworten kann ich verzichten. Bitte Peter vergnüg dich doch > wo anders. Der Versuch zeigt aber das du überhaupt nicht verstanden hast wie eine define arbeitet. Und das sind die Grundlagen von C. Funktionspointer kommen bei den Grundlagen nicht vor.
Gast
#3492488
>Ich möchte das der >Preprozessor mir komfortabel die Funktionen erzeugt: So, z.B.: #define FUNCTION(suffix) FUNCTION##suffix##_test() extern FUNCTION(_66); gibt (gcc -E): # 1 "<built-in>" # 1 "<command-line>" extern FUNCTION_66_test();
uiipsdof schrieb: > So, z.B.: Jaja, dann mach das mal mit 'ner Variablen statt Deiner "_66".
Gast
#3492544
Keep it simple: marco polo schrieb: > int main() > { > int i; > function1test(); function2test(); function3test(); function4test(); function5test(); function6test(); function7test(); function8test(); function9test(); function10test(); > return 0; > } Problem gelöst und keine Verständnisprobleme.
Ursprünglich hatte ich dieses Makro verwendet: #define EXECFUNCTION(name, wert) (function##name##test(wert)) und das dann z.B. so aufgerufen int i=2; EXECFUNCTION(1, i); Funktioniert, aber nur mit einer Funktion! Ich dachte halt der Preprozessor kann ein bischen mehr und wie ein script oder awk auch Schleifen mit Iterationen ausführen. Warscheinlich war ich auf dem Holzweg.
So geht's:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
Man braucht dazu die Boost.Preprocessor-Bibliothek, die man hier bekommt: http://www.boost.org/ Boost ist zwar eine C++-Bibliothek, das Präprozessorzeugs funktioniert aber auch mit C.
Na ja, ob das der TO aber so genau wissen wollte ;) Oliver
Vielen Dank Yalu, ich werds gleich mal ausprobieren! Oliver S. schrieb: > Na ja, ob das der TO aber so genau wissen wollte ;) > > Oliver Noch so einer mit ner unqualifizierten Bemerkung. Was ist denn das hier für ein negatives Karma? :-)
marco polo schrieb: > Gute Idee mit den Funktionszeigern, Das widerspricht übrigens deinem dem unmittelbar voran gehenden Posting ("auf solche Antworten kann ich verzichten"). Ja, man kann (wie das von Yalu gepostete Beispiel zeigt) natürlich den Präprozessor für ziemlich viel Quatsch missbrauchen, für den er nie konzipiert worden ist. Aber man muss das nicht tun, und sehr oft finden sich viel elegantere Lösungen. Ein Array mit Funktionszeigern wurde dir ja schon genannt, aber auch eine Liste kann hier Sinn haben (wenn "next_function"-Zeiger nicht NULL, dann mach dort weiter).
Gast
#3493002
Wehe hier sagt noch einer: "Das geht nicht oder ist Unsinn", dann kommt marc-o polo aus dem Bildschirm und gibt Dir was auf die Tastatur! Was ich nur nicht verstehe ist was soll das Ganze? Selbst wenn ich automatisiert 99 Unikate von Funktionsnamen generiere, gibt es die Funktionen selbst doch nicht. Automatisiert kann ich mit vielen Tricks auch 99 Funktionen erstellen, aber über den A-H-Effekt geht das ganze wohl nicht hinaus. Oder kennt hier jemand einen, der 99 gleiche Funktionen gebrauchen kann? Kann es sein, dass hier Quatsch mit Sauce produziert werden soll? Oder ist's für 'ne Doktorarbeit? Ihr wisst schon: Viel Text mit reduzierter Aussagekraft - geht aber!
Jörg Wunsch schrieb: > marco polo schrieb: >> Gute Idee mit den Funktionszeigern, > > Das widerspricht übrigens deinem dem unmittelbar voran gehenden Posting > ("auf solche Antworten kann ich verzichten"). > > Ja, man kann (wie das von Yalu gepostete Beispiel zeigt) natürlich > den Präprozessor für ziemlich viel Quatsch missbrauchen, für den er > nie konzipiert worden ist. > > Aber man muss das nicht tun, und sehr oft finden sich viel elegantere > Lösungen. Ein Array mit Funktionszeigern wurde dir ja schon genannt, > aber auch eine Liste kann hier Sinn haben (wenn "next_function"-Zeiger > nicht NULL, dann mach dort weiter). Ja da war ich wohl etwas schnell mit dem Zurückschreiben. Wenn mir jemand was über Sinn und Unsinn erzählen will, werd ich immer hellhörig. Geht mir im Übrigen auch bei Produkten so, die Smart im Namen haben. Yalus Lösung funktioniert super (wie unten); Funktionszeiger erfüllen sicher den Zweck auch. Aber das probier ich morgen. Vielen Dank Euch für die Mühe!
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
output: function1 function2 function3
Gast
#3493021
marco polo schrieb: > Yalus Lösung funktioniert super (wie unten); Funktionszeiger erfüllen > sicher den Zweck auch. Aber das probier ich morgen. Ich hol' schonmal Popcorn ;) Oliver
Oliver schrieb: > marco polo schrieb: >> Yalus Lösung funktioniert super (wie unten); Funktionszeiger erfüllen >> sicher den Zweck auch. Aber das probier ich morgen. > > Ich hol' schonmal Popcorn ;) > > Oliver Mach das, aber pass auf das dir nicht die Tränen kommen :-P
1 | |
2 | |
3 | |
4 | |
Und wo ist jetzt deine Variable i und die For Next Schleife?
Amateur schrieb: > Wehe hier sagt noch einer: "Das geht nicht oder ist Unsinn", dann kommt > marc-o polo aus dem Bildschirm und gibt Dir was auf die Tastatur! > > Was ich nur nicht verstehe ist was soll das Ganze? > > Selbst wenn ich automatisiert 99 Unikate von Funktionsnamen generiere, > gibt es die Funktionen selbst doch nicht. > > Automatisiert kann ich mit vielen Tricks auch 99 Funktionen erstellen, > aber über den A-H-Effekt geht das ganze wohl nicht hinaus. > Oder kennt hier jemand einen, der 99 gleiche Funktionen gebrauchen kann? > > Kann es sein, dass hier Quatsch mit Sauce produziert werden soll? > > Oder ist's für 'ne Doktorarbeit? Ihr wisst schon: Viel Text mit > reduzierter Aussagekraft - geht aber! Okay, ich gebs zu. Ich habe mehr als 99 Unikatfunktionen, und ja ich kann das gut gebrauchen. Man kann z.B. Portpin Eigenschaften setzen für Unit-Tests. Oder Laufzeiten automatisch generierter Funktionen ermitteln. Sicher kann man alles viel einfacher machen, aber ich bin halt nicht so helle wie Eure Majestät.
Steffen N. schrieb: >
1 | |
2 | |
3 | |
4 | |
5 | |
> > Und wo ist jetzt deine Variable i und die For Next Schleife? Hallo Steffen, mit einer zur Laufzeit ausgeführten Schleife funktioniert es nicht, da der Preprocessor vor dem Compile über den C/C++-code Text läuft und nur Textersetzungen macht. i war nur ein Vorwand um mein Vorhaben zu verbildlichen. Das Makro BOOST_PP_REPEAT_FROM_TO ist eine Erweiterung, mit der man automatisch C/C++-Code Text o.ä erzeugen kann. Der gcc Preprocessor kann keine Zahl incrementieren und diese in den C/C++-Code als Text einfügen, deswegen die boost-lib. Soviel zu meinem "Text mit reduzierter Aussagekraft" ;-) .
Noch eine abwegige Idee, die ohne boost auskommt: Alle möglichen Schleifen in einem Header vordefinieren. Diesen schreibt man sinnvollerweise nicht von Hand. Irgendwann wird es wahrscheinlich sehr langsam oder der Preprocessor kommt an seine Grenzen.
1 | |
2 | |
3 | |
4 | |
5 | |
wird zu
1 | |
2 | |
3 | |
4 | |
Gast
#3493274
Tom K. schrieb: > Noch eine abwegige Idee, Ich hab auch eine, die ist noch abwegiger: C/C++-Buch kaufen, und die Sprachen lernen. Ist aber ziemlich oldschool... Oliver
marco polo schrieb: > Man kann z.B. Portpin Eigenschaften setzen für Unit-Tests. Du willst also die Arduino-Lib nachentwickeln, bloß mit erheblich mehr Aufwand. Da sind nämlich Funktionen drin für den Pinzugriff als Nummer. Die Lib ist aber auch kein Hexenwerk. Man braucht nur ein Array mit den Portadressen (A..L) und eins mit 8 Bitmasken. Schon ab 2 Funktionen, die sich ähnlich sind, überlege ich, was ist der Unterschied und versuche sie zusammen zu fassen.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.