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.
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
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.
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! ;-)
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:
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 ;-)
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.
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.
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.
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
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.
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
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.
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
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.
>> 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.
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.
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
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...
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.
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.
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..