Forum: Compiler & IDEs Makro mit Anweisung und Abfrage möglich?


von Sebastian B. (mircobolle)


Lesenswert?

Hallo liebe Makro-Freunde und Freundinne,

folgendes Problem:

ich möchte folgende Anweisungen in ein Makro packen:

1)  x += 1;
2)  x =  x % y;

Jetzt kommt noch die Abfrage:

3) if (x == 0) { ... }

ist es möglich das ALLES in EIN Makro zu packen??

Ich habe jetzt mal sowas probiert:
#define MACRO(X,Y) X+=1;X=X%Y;

aber ne Abfrage ist hier nicht mehr möglich?!

Jemand eine Idee ??

Danke!!

von yalu (Gast)


Lesenswert?

Du kannst in das Makro so ziemlich alles packen, was du lustig bist,
also auch if-Konstrukte, Funktionen, Datenstrukturen oder auch nur
Fragmente davon. Ich sehe gerade dein Problem nicht ganz.

Da der Präprozessor nur Text ersetzt, musst du allerdings darauf achten,
dass die Ersetzung im Kontext des Makroaufrufs zu einem sinnvollen
Ergebnis führt. Besonders zu beachten ist hier die richtige Klammerung
und die Verwendung von Semikola.

von Volker (Gast)


Lesenswert?

#define MACRO(X,Y) do { X++; X%=Y; if (X == 0) {...} } while(0)

von Sebastian B. (mircobolle)


Lesenswert?

Volker wrote:
> #define MACRO(X,Y) do { X++; X%=Y; if (X == 0) {...} } while(0)

danke für die Antworten.

Ich habe mich wahrscheinlich nicht klar genug ausgedrückt.

Was ich eigentlich will ist eine Art MACRO Schedule Hilfe.

x += 1;  -> zählt den Counter hoch, das ganze wird im 1 ms Takt 
aufgerufen

x = x % y; -> y ist die Task-Zeit z.b. 3 - alle 3 ms

und dieser Task() soll dann aufgerufen werden, wenn x == 0 ist!

ich könnte natürlich sowas schreiben:

#define MACRO(X,Y) X+=1;X=X%Y;

aber dann geht ja sowas nicht:
1
if (MACRO(X,10) == 0){ // Syntax Error
2
   Task();
3
}

wenn ich das IF ins makro packe, dann ist ja der Task Aufruf aussen vor!

Ich hoffe mein Problem ist jetzt etwas deutlich geworden. :)

Danke

von Nubsi (Gast)


Lesenswert?

1.)  Nenn es nicht MACRO, gibt ihm einen aussagekräftigen Namen.

2.) Was du willst, könnte sich relativ leicht durch eine Funktion 
erledigen lassen.

von Christian S. (manatarms)


Lesenswert?

Es geht doch MACRO(X,Y,TASK)

Packst du halt den Funtkionsnamen mit rein.

von Sebastian B. (mircobolle)


Lesenswert?

Nubsi wrote:
> 1.)  Nenn es nicht MACRO, gibt ihm einen aussagekräftigen Namen.
das mit MACRO war jetzt nur ein Beispiel fürs Forum. Im Code setzt ich 
natürlich vernünftige Namen ein.

> 2.) Was du willst, könnte sich relativ leicht durch eine Funktion
> erledigen lassen.
Naja, aber ich wollte mir halt den Funktionsoverhead durch ein Makro 
sparen. So hätte ich ja einen Funktionssprung pro Task Überprüfung.

Insgesamt sind es 10 Task.

von Sebastian B. (mircobolle)


Lesenswert?

Christian S. wrote:
> Es geht doch MACRO(X,Y,TASK)
>
> Packst du halt den Funtkionsnamen mit rein.

du meinst
1
#define TASK_SCHEDULER(X,Y,TASK) X+=1;X=X%Y; (X==0)?TASK;

wie würde ich das dann effektiv verwenden?
So?
1
TASK_SCHEDULER (TASK_1_COUNTER,TASK_1_COMPARE,Task_1());

Danke!

(ungetestet)

von gast (Gast)


Lesenswert?

schonmal das Wort inline gehört?
1
static inline void funktion ( void );

eine so deklarierte Funktion wird vom Compiler an der stelle eingesetzt 
ohne, dass Overhead entsteht.
Dazu muss aber die Optimierung aktiviert sein.

von Sebastian B. (mircobolle)


Lesenswert?

gast wrote:
> schonmal das Wort inline gehört?
>
>
1
> static inline void funktion ( void );
2
>
>
> eine so deklarierte Funktion wird vom Compiler an der stelle eingesetzt
> ohne, dass Overhead entsteht.
> Dazu muss aber die Optimierung aktiviert sein.

inline kenne ich schon, aber dann müsste ich dieser Funktion ja einen 
Funktionspointer auf meinen Task geben oder 10 inline Funktionen 
definieren, schließlich habe ich ja auch 10 Task.

Aber danke für den Tipp!!

von Detlev T. (detlevt)


Lesenswert?

Sebastian B. wrote:

> #define MACRO(X,Y) X+=1;X=X%Y;
>
> aber dann geht ja sowas nicht:
>
>
1
> if (MACRO(X,10) == 0){ // Syntax Error
2
>    Task();
3
> }
4
>

Wenn du das Macro in einem Ausdruck verwenden willst, darfst du 
natürlich erst einmal kein Semikolon verwenden. Bei deinem speziellen 
Problem eignet sich der Kommaoperator:
1
#define MACRO(X,Y) (X+=1,X%Y)
Oder man schreibt es gleich in einen Ausdruck:
1
#define MACRO(X,Y) (++X%Y)

von Sebastian B. (mircobolle)


Lesenswert?

So lässt sich das Makro nun compilieren:
1
#define mSYSTEM_MANAGER_Task(X,Y,TASK) X+=1;X=X%Y;if(X==0){TASK();}

und so aufrufen
1
     /* BUTTON TASK */ 
2
     if (SYSTEM_MANAGER_ExecTask(SYSTEM_MANAGER_TASK_BUTTON)==true){
3
        mSYSTEM_MANAGER_Task(u8_button_sample,10,BUTTON_Sample);
4
     }

Hinweis: SYSTEM_MANAGER_ExecTask prüft ob der Task im momentanen 
Systemzustand ausgeführt werden darf.

viele grüße

von Christian S. (manatarms)


Lesenswert?

#define MACRO(X,Y,TASK) {X++;X=X%Y;TASK();}

So meinte ich das.

von Christian S. (manatarms)


Lesenswert?

UPS..

Eigentlich mit if... aber hast es ja schon raus bekommen.

von Sebastian B. (mircobolle)


Lesenswert?

Christian S. wrote:
> UPS..
>
> Eigentlich mit if... aber hast es ja schon raus bekommen.

Nochmals ein DICKES DANKE in das Forum :-)

Der Code sieht jetzt um einiges übersichtlicher aus! :-)

Danke && Ciao ;-)

von gast (Gast)


Lesenswert?

Ich glaub du hast gerade ein Brett vor dem Kopf vor lauter Makro ;-)
Meinte das mit der inline Funktion anders.
1
if ( funktion ( x, y ) == 0 )
2
{
3
  task();
4
}

von Sebastian B. (mircobolle)


Lesenswert?

gast wrote:
> Ich glaub du hast gerade ein Brett vor dem Kopf vor lauter Makro ;-)
> Meinte das mit der inline Funktion anders.
>
>
1
> if ( funktion ( x, y ) == 0 )
2
> {
3
>   task();
4
> }
5
>

achso, ja, das wäre natürlich auch eine schlanke Möglichkeit!
Danke für den Tipp. ;-)

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Sebastian B. wrote:
> inline kenne ich schon, aber dann müsste ich dieser Funktion ja einen
> Funktionspointer auf meinen Task geben

Und wo genau ist da das Problem? Funktionen und (globale) Variablen 
werden doch letztlich sowieso über Adressen referenziert.

Das hier
1
static inline void fSYSTEM_MANAGER_Task(unsigned char *X, unsigned char Y,
2
                                        void (TASK)(void))
3
{
4
    *X += 1;
5
    *X  = *X % Y;
6
    if (*X == 0) {
7
        TASK();
8
    }
9
}

Aufruf mit:
1
fSYSTEM_MANAGER_Task(&u8_button_sample,10,BUTTON_Sample);

resultiert bei mir in genau dem gleichen Code wie die Variante mit Makro 
und kann -- im Gegensatz zum Makro -- bei Bedarf auch noch einfach 
entfehlert werden. Typüberprüfung zwecks Illusion einer gewissen 
Sicherheit gibt's gratis dazu.

Gruß
Marcus

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.