Forum: PC-Programmierung codegenerierun mit define


von define (Gast)


Lesenswert?

Hallo,

ich versuche Variablen etc. per define erzeugen zu lassen. Was ist an 
folgendem Code falsch?
1
C
2
3
#include <stdio.h>
4
#include <stdlib.h>
5
6
typedef void (*p_func) (void);
7
8
typedef struct _abc{
9
    p_func a;
10
    p_func b;
11
    p_func c;
12
} abc_struct;
13
14
15
void afuna();
16
void afunb();
17
void afunc();
18
19
#define macro1(xxx)  (& ## xxx ## funa)
20
#define macro2(xxx)  (& ## xxx ## funb)
21
#define macro3(xxx)  (& ## xxx ## func)
22
23
abc_struct test1 = {&afuna,&afunb,&afunc};
24
abc_struct test2 = {macro1(a), macro2(a), macro3(a)};
25
26
27
int main(int argc, char *argv[]) {
28
    
29
    
30
    printf("TEST\n");
31
32
    return 0;
33
}
34
35
36
void afuna(){
37
};
38
void afunb(){
39
};
40
void afunc(){
41
};

Danke. Ich arbeite mit DevCpp. Kann ich mir das Ergebniss des 
Präprozessors anzeigen lassen?

von Nils S. (kruemeltee) Benutzerseite


Lesenswert?

define schrieb:
> Kann ich mir das Ergebniss des
> Präprozessors anzeigen lassen?

#error variable
#warn(ing?) variable

Achso, Hausaufgaben alleine machen!

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

define schrieb:
> Was ist an folgendem Code falsch?

Was sagt denn dein Compiler dazu?

von Yalu X. (yalu) (Moderator)


Lesenswert?

Das Makroargument xxx und funa müssen mit ## zusammengeklebt werden,
damit daraus ein einzelner Identifier entsteht. Soweit ist alles
richtig. Aber was möchtest du mit dem ## zwischen & und xxx bezwecken?
Diese beide Dinge müssen (und dürfen) nicht vereinigt werden.

Lies dazu, wie von Rolf vorgeschlagen, auch die Fehlermeldung des
Compilers. Die sagt nämlich in Kurzform ziemlich genau das oben
Geschriebene aus.

define schrieb:
> Ergebniss des Präprozessors anzeigen lassen?

Der GCC macht das mit der Option -E. Wie du DevCPP dazu bringst, GCC mit
dieser Option aufzurufen, weiß ich aber auch nicht.

Nils S. schrieb:
> #error variable
> #warn(ing?) variable

Das wird nicht viel helfen, weil #error und #warning keine Makros
expandieren.

: Bearbeitet durch Moderator
von define (Gast)


Lesenswert?

Danke für die Antworten. Es scheitert etwas an der Bedienung von DevCpp. 
Ich möchte mit dem Marco das gleiche erzeugen wie in test1 beschrieben. 
Deswegen habe ich versucht ein & davor zu kleben. Wie kann ich mit dem 
Markro eine Adresse an einen Pointer übergeben, wenn ich es so nicht 
drankleben darf?.
Vielen Dank für die Hilfe.

von Rolf M. (rmagnus)


Lesenswert?

define schrieb:
> Danke für die Antworten. Es scheitert etwas an der Bedienung von DevCpp.
> Ich möchte mit dem Marco das gleiche erzeugen wie in test1 beschrieben.
> Deswegen habe ich versucht ein & davor zu kleben. Wie kann ich mit dem
> Markro eine Adresse an einen Pointer übergeben, wenn ich es so nicht
> drankleben darf?.

Indem du es einfach nur davor schreibst, statt es mit ## "dranzukleben".
Der Token-Pasting-Operator fügt die ihm übergebenen Tokens zu einem 
einzigen zusammen. Mit "&afuna" komplett als ein Token kann der Compiler 
aber nichts anfangen, da das & ein eigenes Token sein muss.

von Karl H. (kbuchegg)


Lesenswert?

define schrieb:
> Danke für die Antworten. Es scheitert etwas an der Bedienung von DevCpp.
> Ich möchte mit dem Marco das gleiche erzeugen wie in test1 beschrieben.
> Deswegen habe ich versucht ein & davor zu kleben. Wie kann ich mit dem
> Markro eine Adresse an einen Pointer übergeben, wenn ich es so nicht
> drankleben darf?.

Hier, in
1
abc_struct test1 = {&afuna,&afunb,&afunc};
besteht jede Initialisierung aus 2 Tokens.
Da ist zum einen die Bezeichnung, zb "afuna" und dann ist da der 
Operator &, der aussagt, dass davon die Adresse zu nehmen ist.
Du könntest das auch als
1
abc_struct test1 = { & afuna, & afunb, & afunc };
schreiben, oder als
1
abc_struct test1 = { &
2
                     afuna, & afunb, &
3
                     afunc
4
                   };
wenn du willst. Der & hat mit dem afuna erst mal syntaktisch nichts zu 
tun.
Nur weil du in C alles in einer Wurscht schreiben kannst, weil die 
Syntax so gebaut ist, dass immer klar ist, wo eine 'Einheit' anfängt und 
wo sie aufhört, bedeutet das nicht, dass man das auch in einer Wurscht 
schreiben muss. Dementsprechend muss man auch nicht mit einem 
Token-Pasting Operator im Präprozessor alles zusammenpappen.

: Bearbeitet durch User
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.