Makro mit Anweisung und Abfrage möglich?

OP #1035901
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
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.
OP
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
OP
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.
OP
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)
Gast
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.
OP
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!!
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)
OP
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
Gast
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
}
OP
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. ;-)
Persönliche Seite
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

Eine eigene Frage? Dieser Thread ist über 18 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.