Hallo Leute, mal me kurze Frage: Kann man mit einem define mehrere Anweisungen ausführen und wenn ja, wie trennt man diese. Beispiel:
1 | #define a1 PORTB |= (1 <<PB1) PORTA |= (1 <<PA0)
|
|
Forum: Mikrocontroller und Digitale Elektronik Mehrere Anweisungen hinter einem DefineHallo Leute, mal me kurze Frage: Kann man mit einem define mehrere Anweisungen ausführen und wenn ja, wie trennt man diese. Beispiel:
Ja kann man. Diese trennt man mit einem Semikolon. Am besten fasst du die Anweisungen in einer do-while Schleife zusammen, da sich diese wie eine einzige Anweisung verhält:
Hier steht auch noch was dazu: http://www.mikrocontroller.net/articles/C-Pr%C3%A4prozessor#.23define_f.C3.BCr_eine_Codesequenz be stucki schrieb: > Ja kann man. Diese trennt man mit einem Semikolon. Am besten fasst du > die Anweisungen in einer do-while Schleife zusammen, da sich diese wie > eine einzige Anweisung verhält: >
Und wenn es ein bisschen umfangreicher wird:
mfg. Thomas Eckmann schrieb: > Und wenn es ein bisschen umfangreicher wird: Hierbei wichtig: Hinter den \ darf kein weiteres Zeichen stehen, auch kein Whitespace (Leerzeichen, Tabs). Wird das Schleifenkonstrukt (do-while) wirklich rückstandslos entfernt, oder behalte ich eine "unsichtbare" Sprung- bzw. Abfrageanweisung zurück? Indem man kein #define verwendet:
Keinerlei Performance/Platz-Nachteil ggü. dem #define, vermeidet aber all die potentiellen Probleme von Makros und die Frickelei mit do-while etc. Dr. Sommer schrieb: > Indem man kein #define verwendet: >
Keinerlei Performance/Platz-Nachteil ggü. dem #define, vermeidet > aber all die potentiellen Probleme von Makros und die Frickelei mit > do-while etc. Wenn der Compiler das kann und will, macht er das auch. In diesem einfachen Beispiel vielleicht sogar von sich aus ohne inline-Deklaration. Aber ein paar Konjunktive gibt es dabei. mfg. Für meine LCD Routine habe ich das hier verwendet und es funktioniert Problemlos:
Amateur schrieb: > Wird das Schleifenkonstrukt (do-while) wirklich rückstandslos entfernt, > oder behalte ich eine "unsichtbare" Sprung- bzw. Abfrageanweisung > zurück? Nein das schmeisst der Compiler vollkommen raus. Ist ja auch vollkommen sinnlos. Eigentlich gehört das auch so #define a1() do{PORTB |= (1 <<PB1); PORTA |= (1 <<PA0);}while(0) Damit kannst/musst du das Makro wie eine Funktion aufrufen a1(); Und fliegst ohne die do... while in einer if-Abfrage voll auf die Fresse. if(bla) a1(); else a2(); Das jetzt mal für den TO, der sich wahrscheinlich fragt, was das soll. mfg. Thomas Eckmann schrieb: > Wenn der Compiler das kann und will, macht er das auch. > In diesem einfachen Beispiel vielleicht sogar von sich aus ohne > inline-Deklaration. Aber ein paar Konjunktive gibt es dabei. Wenn du so paranoid bist schreibst du "__attribute__((always_inline)) inline" dran (nur GCC & Clang), dann wird es garantiert ge-inlined und ist somit garantiert so effizient wie das Makro, provoziert nur viel weniger Probleme. Thomas Eckmann schrieb: > Damit kannst/musst du das Makro wie eine Funktion aufrufen a1(); > Und fliegst ohne die do... while in einer if-Abfrage voll auf die > Fresse. Warum ein Makro schreiben das wie eine Funktion verwendbar ist, wenn man auch einfach eine Funktion schreiben kann? Max H. schrieb: > Wieso sollte es das nicht sein? Weil der Name blöd ist, da weiß keiner was gemeint ist. Was wird denn da eingeschaltet, PWM, UART, LED, USB? Dr. Sommer schrieb: > Weil der Name blöd ist, da weiß keiner was gemeint ist. Max H. schrieb: > Für meine LCD Routine [...] Dr. Sommer schrieb: > Thomas Eckmann schrieb: >> Wenn der Compiler das kann und will, macht er das auch. >> In diesem einfachen Beispiel vielleicht sogar von sich aus ohne >> inline-Deklaration. Aber ein paar Konjunktive gibt es dabei. > Wenn du so paranoid bist schreibst du "__attribute__((always_inline)) > inline" dran (nur GCC & Clang), dann wird es garantiert ge-inlined und > ist somit garantiert so effizient wie das Makro, provoziert nur viel > weniger Probleme. Ich bin nicht paranoid, du A... > Thomas Eckmann schrieb: >> Damit kannst/musst du das Makro wie eine Funktion aufrufen a1(); >> Und fliegst ohne die do... while in einer if-Abfrage voll auf die >> Fresse. > Warum ein Makro schreiben das wie eine Funktion verwendbar ist, wenn > man auch einfach eine Funktion schreiben kann? Hab ich schon geschrieben. mfg. Max H. schrieb: > Max H. schrieb: >> Für meine LCD Routine [...] Das muss man dann aber immer manuell dazuschreiben. EnableLCD wäre doch wesentlich deskriptiver gewesen. Auch wenn euch das Beispiel nicht passt, mehrere Aweisungen hinter einem #define sind also problemlos ohne das do while möglich... Und um das zu zeigen ist der Namen des defines irrelevant... Max H. schrieb: > Auch wenn euch das Beispiel nicht passt, mehrere Aweisungen hinter > einem > #define sind also problemlos ohne das do while möglich... > Und um das zu zeigen ist der Namen des defines irrelevant... Und was passiert dann?
Und was wird dadraus? (Einrückung zur Verdeutlichung dessen was passiert)
Die Initialisierung erfolgt also immer halb oder ganz, aber nie gar nicht. Ob das beansichtigt war? Noch hässlicher wirds dann wenn man temporäre Variablen und Paramenter benötigt... Um sowas muss man sich keine Gedanken machen wenn man einfach eine Funktion verwendet. Max H. schrieb: > Auch wenn euch das Beispiel nicht passt, mehrere Aweisungen hinter einem > #define sind also problemlos ohne das do while möglich... > Und um das zu zeigen ist der Namen des defines irrelevant... Weil du Glück hast und das Makro nur auf eine Art und Weise benutzt. Es ist dein Makro und nur in deinen Programmen von dir verwendbar.
funktioniert. In diesem speziellen Fall nicht relevant, aber:
dann steht da plötzlich:
Das Delay wird nur ausgeführt wenn bla true ist, der Rest immer. Und das else steht ohne if völlig alleine da. Deswegen gehört die do...while()-Schleife da herum. Der Name ist trotzdem nicht aussagekräftig. Makros sind oft Scheisse. Es sei denn, man macht es richtg. Und dann kann man noch Stunden darüber diskutieren, ob man die überhaupt verwenden soll. Die do...while -Krücke ist für viele ein Argument davon abzuraten. Entweder man benutzt diese Krücke oder man benutzt keine Makros mit mehreren Anweisungen. Mit deinem Makro schiesst du dir nur selbst ins Knie. Mit diesem speziellen wahrscheinlich nicht. Aber wenn du deine Makros immer so schreibst, mit Sicherheit irgendwann. Und wenn die if-Bedingung dann ohne else dasteht, gibt es nicht einmal eine Fehlermeldung. mfg. Danke für die ganzen Antworten. Ich denke ich werde es dann mal mit dem oberen do/while ausprobieren. Finde inline Funktionen auch am Schönsten. Allerdings nur mit Attribut "always inline". Ich hab mal recht viel mit inline experimentiert und bin zu dem Ergebnis gekommen: Eine Funktion nur als "inline" zu definieren bringt garnichts. Mit eingeschalteter Optimierung wird der gcc sie sowieso inlinen, wenn er der Meinung ist es bringt was. Und andersherum wird er sie nicht inlinen wenn der Code deswegen zu groß wird (z.B. bei mehreren Aufrufen), trotz "inline". Kann das jemand so bestätigen? Haro schrieb: > Und andersherum wird er sie nicht inlinen wenn der Code deswegen zu groß > wird (z.B. bei mehreren Aufrufen), trotz "inline". > > Kann das jemand so bestätigen Leider ja. Es ist sogar noch schlimmer: Selbst wenn der Code durch (sogar mehrfach auftretendes) inlinen kleiner würde (durch optimieren der Operation und wegfallen des Aufrufs&Parameter-Übergabe -Overhead) macht der GCC das nicht immer. Daher muss man sich mit __attribute__((always_inline)) behelfen. In C++11 ist sogar eine Standard-Notation dafür vorgesehen (um Compiler-unabhängig zu sein) aber die unterstützt GCC noch nicht :-/ Aber alles besser als ein Makro, insbesondere eines für das es 0 Grund gibt, ein Makro zu sein (wie Code-Generierung, impliziter Zugriff auf lokale Variablen (hässlich) etc.) 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.
|
|