Makro mit Anweisung und Abfrage möglich?

#1035901
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!!
Gast #1035933
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.
#1035953
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
#1035978
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.
Gast #1035993
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.
#1036002
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!!
#1036009
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)
#1036023
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
Persönliche Seite #1036862
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

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