Forum: Mikrocontroller und Digitale Elektronik Alternative zu mehrzeiligen Makros in C allgemien oder speziell in IAR EWB


von pppeter (Gast)


Lesenswert?

Gibt es eine Möglichkeit bestimmte Code-Blöcke zu definieren die mit 
einem Befehl dann an verschiedenen Stellen eingefügt werden können?

Mehrzeilige Makros lassen sich nur umständlich erstellen und umständlich 
von Hand formatieren und auch automatische 
Quellcodeformatierprogramme(die ich teilweise gezwungenermaßen einsetzen 
muss) kommen damit nicht klar.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Du meinst Inline-Funktionen.

von pppeter (Gast)


Lesenswert?

Frank M. schrieb:
> Du meinst Inline-Funktionen.

Nein, leider nicht. Ich habe auch erst gedacht das Inline-Funktionen das 
sind was ich suche, scheint aber nicht so zu sein:
Beitrag "Inline Funktionen und in ihnen deklarierte variablen"

von Peter D. (peda)


Lesenswert?

pppeter schrieb:
> Mehrzeilige Makros lassen sich nur umständlich erstellen und umständlich
> von Hand formatieren

Warum?
Der Unterschiede sind doch nur das '\' am Zeilenende und das man kein 
"return" verwenden kann.

Oder nimm Inline-Funktionen.


Peter

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

pppeter schrieb:
> Nein, leider nicht. Ich habe auch erst gedacht das Inline-Funktionen das
> sind was ich suche, scheint aber nicht so zu sein:
> Beitrag "Inline Funktionen und in ihnen deklarierte variablen"

Stimmt, da hatte ich Dir sogar geantwortet :-)

Warum willst Du sie denn nicht nehmen? Wegen den lokalen Variablen, die 
dann übergeben werden müssen? Warum denn nicht? Die Übergabewerte werden 
bei Inline-Funktionen wieder komplett rausoptimiert, so dass am Ende an 
µC-Code genau das übrigbleibt, was Du eigentlich wolltest. Der Vorteil 
dieser Wahl ist: Du kannst später immer noch eine "richtige" Funktion 
draus machen, wenn der Code zu komplex wird.

Sonst bleiben da nur noch Makros übrig, wenn Du wirklich Deinen C-Code 
1:1 haben möchtest. Wie Peter schon sagte: Hier musst Du lediglich ein 
Backslash an jede Zeile hängen, sonst kann es genauso aussehen wie Dein 
restlicher C-Code.

Aber halt... da fällt mir noch eine 3. Möglichkeit ein, nämlich 
includes.

Du schreibst Deinen Code-Block, den Du auslagern willst, in eine Datei 
foo.h und rufst diese mit

#include "foo.h"

an der Stelle auf, wo der Code eingefügt werden soll. Das geht in jeder 
beliebigen Zeile Deines C-Codes - auch mitten in Funktionen.

von Klaus (Gast)


Lesenswert?

Frank M. schrieb:
> Du schreibst Deinen Code-Block, den Du auslagern willst, in eine Datei
> foo.h und rufst diese mit
>
> #include "foo.h"
>
> an der Stelle auf, wo der Code eingefügt werden soll. Das geht in jeder
> beliebigen Zeile Deines C-Codes - auch mitten in Funktionen.

Pfui, Bah! Rede nicht so perverses Zeuch hier! ;-)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Klaus schrieb:
> Pfui, Bah! Rede nicht so perverses Zeuch hier! ;-)

Er fragte nach den technischen Möglichkeiten, ob das pervers ist oder 
nicht, soll er doch entscheiden. ;-)

Ich würde sowas auch nicht machen. Besser ist es, den Source sauber zu 
modularisieren und den Rest den Compiler machen zu lassen - zum Beispiel 
das Inlinen von Funktionen. Es gibt aber immer wieder Leute, die den 
Compiler bzw. die Sprache "vergewaltigen" wollen. Ich habe mir vor ca. 
20 Jahren mal den Original-C-Quelltext der Bourne-Shell unter Unix 
angeschaut. Was da Stephen R. Bourne Ende der 70er mit dem 
C-Preprocessor veranstaltet hat, um den Quelltext Algol-ähnlich aussehen 
zu lassen, ging auf keine Hutschnur ;-)

Ein paar Beispiele (aus dem Kopf):

#define BEGIN {
#define END }
#define IF if
#define EQUALS ==

Das sah dann so aus:
1
IF (foo EQUALS bar)
2
BEGIN
3
   foo = 0;
4
END

von Klaus W. (mfgkw)


Lesenswert?

Frank M. schrieb:
> #define END }

Wenn man noch ein ; vor dem } einfügt, kann man auch standesgemäß wie in 
Pascal das letzte ; im Block weglassen.
Ein paar ; sind dann überflüssig, aber sie werden ja imemr nur temporär 
generiert ;-)

von Meister E. (edson)


Lesenswert?

Frank M. schrieb:
> Es gibt aber immer wieder Leute, die den
> Compiler bzw. die Sprache "vergewaltigen" wollen. Ich habe mir vor ca.
> 20 Jahren mal den Original-C-Quelltext der Bourne-Shell unter Unix
> angeschaut. Was da Stephen R. Bourne Ende der 70er mit dem
> C-Preprocessor veranstaltet hat, um den Quelltext Algol-ähnlich aussehen
> zu lassen, ging auf keine Hutschnur ;-)

Vielleicht ging es ihm ja nicht um das Aussehen, sondern die Möglichkeit 
seine Algol-Sourcen per Copy&Paste dem C-Compiler zuzuführen?
Eigentlich ein gutes Beispiel für die Flexibilität von C.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Klaus Wachtler schrieb:
> Wenn man noch ein ; vor dem } einfügt, kann man auch standesgemäß wie in
> Pascal das letzte ; im Block weglassen.

Stimmt! In Algol 68 geht das auch, ich habe mir gerade mal

  http://en.wikipedia.org/wiki/ALGOL_68C

näher angeschaut. Bourne hat ja Anfang der 70er selbst am Algol 68 
Compiler mitgewirkt.

Kann also gut sein, dass das END-Makro tatsächlich auch ein Semikolon 
beinhaltete... ist zu lang her, um mich zu erinnern.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Meister Eder schrieb:
> Vielleicht ging es ihm ja nicht um das Aussehen, sondern die Möglichkeit
> seine Algol-Sourcen per Copy&Paste dem C-Compiler zuzuführen?

Wenn ich so darüber nachdenke.... hast Du wahrscheinlich Recht. 1971 hat 
Bourne am Algol-Compiler gearbeitet, wahrscheinlich hat er schon damals 
Teile oder zumindest Prototypen der späteren Bourne-Shell zunächst in 
Algol programmiert...

> Eigentlich ein gutes Beispiel für die Flexibilität von C.

Jepp.

von pppeter (Gast)


Lesenswert?

Peter Dannegger schrieb:
> pppeter schrieb:
>> Mehrzeilige Makros lassen sich nur umständlich erstellen und umständlich
>> von Hand formatieren
>
> Warum?
> Der Unterschiede sind doch nur das '\' am Zeilenende und das man kein
> "return" verwenden kann.

ja das reicht doch schon an umständlichkeit oder? :D
wenn ich das makro verändern muss und zeilen länger oder kürzer werden 
muss ich dem mist ja jedes mal neu ausrichten und wenn ich neue zeilen 
einfügen erst mit etlichen tabs zum zeilenende kommen. außerdem gefällt 
mir es nicht das ich diese makro(-funktionen) am anfang der datei oder 
in einem header definieren muss. da sie ja eher der charakter einer 
funktion haben würde ich sie gerne ans ende der c-file setzen.
kann man denn prototypen von makros erstellen? xD

wenn ich inline funktionen nehmen würde müsste ich auch blos die 
variablen außerhalb erstellen und dann sogar noch einen zeiger auf sie 
übergeben, das gefällt mir auch nicht.

an #include habe ich auch schon gedacht aber dann müsste ich für jeden 
block eine datei anlegen, das ist auch mist.


So eine Preprocessor-Vergewaltigung wäre schon nicht schlecht^^
vielleicht kann man ja mit einem define wärend eines mehrzeiligen makros 
"\n" als "\ \n" definieren xD

von Klaus W. (mfgkw)


Lesenswert?

Man kann es positiv sehen:
Dadurch, daß lange Makros eher umständlich zu schreiben sind, wird man 
vor noch mehr Quatsch mit Monstermakros verschont; auch so wird schon 
zuviel damit gemurkst.

Sei also dankbar, und schreibe vernünftigen Quelltext.

von Vlad T. (vlad_tepesch)


Lesenswert?

pppeter schrieb:
> wenn ich inline funktionen nehmen würde müsste ich auch blos die
> variablen außerhalb erstellen und dann sogar noch einen zeiger auf sie
> übergeben, das gefällt mir auch nicht.

Ich glaub du hast das Prinzip vernünftiger Modularisierung und den Sinn 
von Gültigkeitsbereichen (Scopes) noch nicht verstanden.

Meine Wärmste Empfehlung ist, dir ein gutes C-Buch zu besorgen und dies 
nachzuholen

von pppeter (Gast)


Lesenswert?

Vlad Tepesch schrieb:
> pppeter schrieb:
>
> Ich glaub du hast das Prinzip vernünftiger Modularisierung und den Sinn
> von Gültigkeitsbereichen (Scopes) noch nicht verstanden.
>
> Meine Wärmste Empfehlung ist, dir ein gutes C-Buch zu besorgen und dies
> nachzuholen

Und ich glaube du hast noch nich gemerkt das ich ohne Probleme auf 
mehrzeilige Makros verzichten kann aber mir es darum geht kurzen und gut 
lesbaren Quelltext zu schreiben.
Würde ich normale Funktionen verwenden dann müsste ich den lokalen Scope 
aufgeben und die Variablen global deklarieren womit ich mehr RAM 
benötigen und der code würde wahrscheinlich langsamer und außerdem würde 
ich höchstwahrscheinlich dem compiler die möglichkeit nehmen ordentlich 
zu optimieren.

Inline Funktionen hätten zwar keine Performance/RAM Nachteile im 
Vergleich zu mehrzeiligen Makros aber sind nicht besser lesbar und auch 
nicht kürzer.

von Vlad T. (vlad_tepesch)


Lesenswert?

pppeter schrieb:
> Und ich glaube du hast noch nich gemerkt das ich ohne Probleme auf
> mehrzeilige Makros verzichten kann aber mir es darum geht kurzen und gut
> lesbaren Quelltext zu schreiben.
> Würde ich normale Funktionen verwenden dann müsste ich den lokalen Scope
> aufgeben und die Variablen global deklarieren womit ich mehr RAM
> benötigen und der code würde wahrscheinlich langsamer und außerdem würde
> ich höchstwahrscheinlich dem compiler die möglichkeit nehmen ordentlich
> zu optimieren.

dieses Statement untermauert meine Vermutung und Empfehlung

pppeter schrieb:
> Inline Funktionen hätten zwar keine Performance/RAM Nachteile im
> Vergleich zu mehrzeiligen Makros aber sind nicht besser lesbar und auch
> nicht kürzer.

aha
inline funktionen sind quasi makros

Makros anders (mit versteckten Seiteneffekten) zu benutzen ist 
normalerweise extrem schlechter Stil.
und leichter verständlich wird Code dadurch garantiert nicht.
Es gibt nur sehr wenige Fälle, wo das wirklich Sinn macht.

edit:
Aber sei es drum. wenn du erfahreneren Programmierern nicht glaubst, ist 
das deine Sache.
Erwarte aber nicht, dass man dir hier mit Freuden hilft, wenn man mal 
solchen Code präsentiert bekommt mit der Bitte um Hilfe, den Fehler zu 
finden. Da wird man dir solchen Code auch erstmal um die Ohren hauen

von Karl H. (kbuchegg)


Lesenswert?

pppeter schrieb:
> Vlad Tepesch schrieb:
>> pppeter schrieb:
>>
>> Ich glaub du hast das Prinzip vernünftiger Modularisierung und den Sinn
>> von Gültigkeitsbereichen (Scopes) noch nicht verstanden.
>>
>> Meine Wärmste Empfehlung ist, dir ein gutes C-Buch zu besorgen und dies
>> nachzuholen
>
> Und ich glaube du hast noch nich gemerkt das ich ohne Probleme auf
> mehrzeilige Makros verzichten kann aber mir es darum geht kurzen und gut
> lesbaren Quelltext zu schreiben.

Na dann. Dann sind inline Funktionen das Mittel der Wahl

> Würde ich normale Funktionen verwenden dann müsste ich den lokalen Scope
> aufgeben und die Variablen global deklarieren

Äh, nein.
Man übergibt Parameter an die Funktionen und damit hat sichs.

Ich hab genauso wie Vlad das Gefühl, das dir in erster Linie fehlendes 
C-Grundlagenwissen im Wege steht.

von pppeter (Gast)


Lesenswert?

>> Würde ich normale Funktionen verwenden dann müsste ich den lokalen Scope
>> aufgeben und die Variablen global deklarieren
>
> Äh, nein.
> Man übergibt Parameter an die Funktionen und damit hat sichs.

Ja stimmt.. hatte das eher so gemeint das wenn ich normale Funktionen 
verwenden will und mir das übergeben etlicher Parameter sparen will dann 
müsste ich globale Variablen nehmen... was ja niemand so machen würde.


Vlad Tepesch schrieb:
> Makros anders (mit versteckten Seiteneffekten) zu benutzen ist
> normalerweise extrem schlechter Stil.
> und leichter verständlich wird Code dadurch garantiert nicht.
> Es gibt nur sehr wenige Fälle, wo das wirklich Sinn macht.

Ob ich nun Codeblöcke mit copy+paste an 10 stellen kopiere oder mit nem 
Makro macht doch keinen Unterschied. Was soll es den für Seiteneffekte 
geben wenn ich ein paar (immer gleiche) lokale Variablen nach einem 
Schema mit Data fülle auf die ein (immer gleicher) Pointer zeigt?

Ich habe keine lust mehr auf die Diskussion, nur weil du ein "erfahrener 
Programmierer" bist musst du dich ja nicht so überheblich verhalten und 
mich hier als Dumm hin stellen.

von Phantomix X. (phantomix)


Lesenswert?

pppeter schrieb:
> Ja stimmt.. hatte das eher so gemeint das wenn ich normale Funktionen
> verwenden will und mir das übergeben etlicher Parameter sparen will dann
> müsste ich globale Variablen nehmen... was ja niemand so machen würde.

Was spricht dagegen, alle Parameter (wenn sie eh zusammegehören) in ein 
struct zu packen und dann nur nen pointer auf die struct zu übergeben?

> Ich habe keine lust mehr auf die Diskussion, nur weil du ein "erfahrener
> Programmierer" bist musst du dich ja nicht so überheblich verhalten und
> mich hier als Dumm hin stellen.

Hat keiner behauptet.
Dumm ist der, der (wider besseren Wissens) Dummes tut. Da du es 
vermutlich nicht besser weißt/wusstest, ist es eher Unkenntnis. und ich 
möchte mich dem Tipp anschließen, lies ein gutes C Buch.

von Klaus (Gast)


Lesenswert?

pppeter schrieb:
> Würde ich normale Funktionen verwenden dann müsste ich den lokalen Scope
> aufgeben und die Variablen global deklarieren

Verstehe ich das jetzt richtig: Funktionen, die ich oder der Compiler 
inlined, dürfen keine localen Variablen haben?

MfG Klaus

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Klaus schrieb:
> Verstehe ich das jetzt richtig

Nein... Der Compiler kann generell jede Funktion inlinen wenn es ihm 
sinnvoll erscheint (mal abgesehen von speziellen Compileranweisungen) 
und ein inline bedeutet auch nicht das sie geinlined werden muss und 
es gibt ob inline oder nicht keinerlei Einschränkungen für den Aufbau 
der Funktion, das ist eine wie jede andere auch...

von pppeter (Gast)


Lesenswert?

Klaus schrieb:
> Verstehe ich das jetzt richtig: Funktionen, die ich oder der Compiler
> inlined, dürfen keine localen Variablen haben?

Nein, du darfst natürlich innerhalb von inline Funktionen lokale 
Variablen verwenden, nur sind diese nach verlassen der Funktion nicht 
mehr "sichtbar", so wie bei normalen Funktionen auch.

Phantomix Ximotnahp schrieb:
> pppeter schrieb:
>> Ja stimmt.. hatte das eher so gemeint das wenn ich normale Funktionen
>> verwenden will und mir das übergeben etlicher Parameter sparen will dann
>> müsste ich globale Variablen nehmen... was ja niemand so machen würde.
>
> Was spricht dagegen, alle Parameter (wenn sie eh zusammegehören) in ein
> struct zu packen und dann nur nen pointer auf die struct zu übergeben?
Werd ich aus interesse mal probieren und mal kucken was der compiler 
dann draus macht wenn ich nur eine der variablen auch wirklich im 
nachfolgenden code verwende.

>[..]und ich möchte mich dem Tipp anschließen, lies ein gutes C Buch.
Ich brauche kein C Buch, höchsten eins über Präprozessoren.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

pppeter schrieb:
> Ich brauche kein C Buch, höchsten eins über Präprozessoren.

Zeig doch mal ein Codebeispiel, wo Du Deine "Blockrepetition" anwenden 
willst.

Häufig sequentiell wiederkehrende Codesequenzen lassen darauf schließen, 
daß irgendwas merkwürdig ist.

von pppeter (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> pppeter schrieb:
>> Ich brauche kein C Buch, höchsten eins über Präprozessoren.
>
> Zeig doch mal ein Codebeispiel, wo Du Deine "Blockrepetition" anwenden
> willst.
sry aber das darf ich leider nicht machen.

ich kanns nur so erklären:
ich bekomme einen Datenstrom (ein pointer auf einen buffer) und dieser 
Datenstrom enthält Information, aber es gibt mehrere Protokolle in denen 
die Information an anderen stellen stehen bzw. auf andere weise 
ausgedrückt werden. Und je nach dem an welche stelle ich mich in meiner 
Statemachine befinde muss ich an gewisse Informationen ran kommen. Und 
die mehrzeiligen Markos die ich nehme sind die schnittstelle zwischen 
Information und Datenstrom. Und wenn ich nur eine Information aus einem 
Pool von z.b. 20 möglichen brauche dan optimiert der Compiler so das 
auch nur diese eine Info "extrahiert" wird und das ohne irgendwelche 
call-Befehle oder etliche RAM-Zugriffe und auch noch alles schön 
Einheitlich, gut Lesbar und Fehlerunanfällig.

..hab nur gehofft da gibts vielleicht ein pragma mit dem ich da noch 
bisschen aufräumen kann im Code oder so..

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.