Adreßoperator



  • pointercrash() schrieb:

    Macros sind da oft die unerwarteten Problemlöser.

    stimmt schon. denk doch nur mal an deine eeprom-variablen. der <beliebiges_wort_einsetzen>-freak hat dir einst gezeigt, wie wunderbar macros die sprache C bereichern können.
    🙂



  • pointercrash() schrieb:

    Tim schrieb:

    Zustimmung. Aber auf höheren Ebenen nimmt man ja auch keine Makros mehr 😉

    Oje, lieber Mod,
    Bodenhaftung verloren 😕

    Wieso? 😕

    pointercrash() schrieb:

    Unter C gibt es nur das, was Präprozessor und Compiler hergeben. Macros sind da oft die unerwarteten Problemlöser.

    Und ebenso oft die (un)erwarteten Problemerzeuger.

    pointercrash() schrieb:

    Das hier ist das C- Forum, vergessen? 🙄

    Und? Was willst du damit sagen?

    @ anything-freak:
    Welches Problem hat das EEPROM-Makro denn gelöst?





  • Tim schrieb:

    Wieso? 😕

    Warum das so ist, weiß ich nicht, aber im ANSI-C- Forum Makros schlechtzureden und von höheren Ebenen zu faseln, ist Themaverfehlung

    Tim schrieb:

    Und ebenso oft die (un)erwarteten Problemerzeuger.

    Ja, und auch Pointer verursachen Probleme bei fehlerhafter Anwendung, trotzdem sind sie zentraler Bestandteil von C. Daß man sie im Elysium der "höheren Ebenen" auch nicht unbedingt braucht, hat doch HIER nichts zu sagen.

    Tim schrieb:

    @ anything-freak:
    Welches Problem hat das EEPROM-Makro denn gelöst?

    sh. voriger Post. Ich fand's schön, wie elegant man das damit machen kann und weil's mich interessiert hat, habe ich ein bißchen mit dem Präp gespielt. Richtig eingesetzt geben die Makros eine weitere Abstraktionsebene, die ich zumindest früher nicht ausreichend gewürdigt habe. Das finde ich im Nachhinein schade.

    Tim schrieb:

    Und? Was willst du damit sagen?

    Du empfiehlst Leuten quasi wegen nicht näher bezeichneter möglicher Probleme beim Autofahren auf die höheren Gänge zu verzichten und verweist darauf, daß in "höheren Ebenen" stufenlose Automatikgetriebe existieren.
    In C wird jedoch noch gekuppelt und geschaltet, sonst fährt's nicht richtig. Hier gehören Makros nicht benörgelt, sondern erklärt, ist doch das C- Forum, oder?



  • pointercrash() schrieb:

    aber im ANSI-C- Forum Makros schlechtzureden .... ist Themaverfehlung
    ...
    Richtig eingesetzt geben die Makros eine weitere Abstraktionsebene...
    ...
    In C wird jedoch noch gekuppelt und geschaltet, sonst fährt's nicht richtig. Hier gehören Makros nicht benörgelt, sondern erklärt....

    super statement, pointercrash. ganz meine meinung 👍 -->∞
    dem ist nichts hinzuzufügen, deshalb unendlich viele 'daumen-hoch'.
    🙂



  • pointercrash() schrieb:

    Tim schrieb:

    Wieso? 😕

    Warum das so ist, weiß ich nicht, aber im ANSI-C- Forum Makros schlechtzureden und von höheren Ebenen zu faseln, ist Themaverfehlung

    1. Ich rede Makros nicht schlecht. Ich finde nur falschen/übermäßigen Einsatz von Function-like-Makros schlecht. Das ist ein Unterschied.
    2. Die "höheren Ebenen" wurden von anderen zuerst benutzt. Bitte nochmal lesen. Danke.

    pointercrash() schrieb:

    Tim schrieb:

    Und ebenso oft die (un)erwarteten Problemerzeuger.

    Ja, und auch Pointer verursachen Probleme bei fehlerhafter Anwendung, trotzdem sind sie zentraler Bestandteil von C.

    Der (eigentlich offensichtliche) Unterschied ist, dass man Zeiger praktisch nicht durch andere Konstrukte ersetzen kann. Die meisten Function-like-Makros aber schon.

    pointercrash() schrieb:

    Daß man sie im Elysium der "höheren Ebenen" auch nicht unbedingt braucht, hat doch HIER nichts zu sagen.

    Spar dir dein Geblubber von wegen "Elysium der "höheren Ebenen"", siehe oben.



  • Tim schrieb:

    1. Ich rede Makros nicht schlecht. Ich finde nur falschen/übermäßigen Einsatz von Function-like-Makros schlecht. Das ist ein Unterschied.

    Ah ja? Was ist denn falsch? Und was zuviel? Erleuchte uns mit Beispielen!

    Tim schrieb:

    2. Die "höheren Ebenen" wurden von anderen zuerst benutzt.

    Jo, aber Du hast den Kontext verdreht. Bitte nochmal lesen. Danke.

    Tim schrieb:

    Der (eigentlich offensichtliche) Unterschied ist, dass man Zeiger praktisch nicht durch andere Konstrukte ersetzen kann. Die meisten Function-like-Makros aber schon.

    Hast Du noch nie Code übernommen, der von jemand produziert wurde, der panische Angst vor Pointern hatte? Es geht auch (fast) ohne, der Code wird halt sehr umständlich. Andererseits hab' ich jetzt einen Teil meiner Libs durch Makros deutlich straffen können, weil mir jemand diese Möglichkeit gezeigt hat. Vorher war das viel umständlicher.

    Tim schrieb:

    Spar dir dein Geblubber ...

    In dem Fall ein Makro zu setzen, war ein sachbezogenes Beispiel und es wurde erläutert, daß der Code sukzessive aufgelöst wird. Es gibt verschiedene Abstraktionsebenen, zum Schluß fällt Maschinencode raus, so war das wohl gemeint. Supertimmi antwortet, daß es in höheren Ebenen keine Makros braucht. Also entweder hat er das Beispiel nicht verstanden oder nur genutzt, seinen "Humor" 🤡 unter Beweis zu stellen.



  • pointercrash() schrieb:

    Tim schrieb:

    1. Ich rede Makros nicht schlecht. Ich finde nur falschen/übermäßigen Einsatz von Function-like-Makros schlecht. Das ist ein Unterschied.

    Ah ja? Was ist denn falsch? Und was zuviel? Erleuchte uns mit Beispielen!

    #define SetBit(a, p) ((a)[(p)>>3] |= (1<<((p)&3)))
    #define GetBit (a, p) (!!((a)[(p)>>3] & (1<<((p)&3))))
    

    - Unnötiger Einsatz von Makro, eine Funktion wäre wesentlich übersichtlicher.
    - Seiteneffekte durch evtl. mehrfache Auswertung von p.
    - Bricht die (ungeschriebene) Regel, dass Makros nur Großbuchstaben enthalten sollten und nicht groß/klein gemischt.

    pointercrash() schrieb:

    Tim schrieb:

    2. Die "höheren Ebenen" wurden von anderen zuerst benutzt.

    Jo, aber Du hast den Kontext verdreht. Bitte nochmal lesen. Danke.

    Bist du dir sicher, dass du überhaupt verstanden hast, was ich mit Ebene meinte? Vielleicht meinte ich ja Abstraktionsebene? Du darfst jetzt darauf herumreiten, dass ich mich unklar ausgedrückt habe...

    pointercrash() schrieb:

    Tim schrieb:

    Der (eigentlich offensichtliche) Unterschied ist, dass man Zeiger praktisch nicht durch andere Konstrukte ersetzen kann. Die meisten Function-like-Makros aber schon.

    Hast Du noch nie Code übernommen, der von jemand produziert wurde, der panische Angst vor Pointern hatte? Es geht auch (fast) ohne, der Code wird halt sehr umständlich.

    Ja, das ist fucked-up Code. Durfte ich schon oft genug wegwerfen.

    pointercrash() schrieb:

    Andererseits hab' ich jetzt einen Teil meiner Libs durch Makros deutlich straffen können, weil mir jemand diese Möglichkeit gezeigt hat. Vorher war das viel umständlicher.

    Erleuchte uns mit Beispielen. Das EEPROM-Beispiel kenne ich schon. Davon war FIELD_OFFSET und FIELD_SIZE sinnvoll. Die anderen beiden hätte man genausogut als Funktion schreiben können.

    pointercrash() schrieb:

    Supertimmi antwortet, daß es in höheren Ebenen keine Makros braucht. Also entweder hat er das Beispiel nicht verstanden oder nur genutzt, seinen "Humor" 🤡 unter Beweis zu stellen.

    Nichts für ungut, aber glaubst du nicht, dass du dich hier gerade in etwas verrennst?



  • Tim schrieb:

    Die anderen beiden hätte man genausogut als Funktion schreiben können.

    zeig mal wie, aber ohne dass die aufrufe komplizierter werden.
    🙂



  • Edit: hier stand erst Mist.

    Naja, gibt man halt Element, Größe des Elements und Offset an. Nicht wirklich tragisch.



  • Tim schrieb:

    #define SetBit(a, p) ((a)[(p)>>3] |= (1<<((p)&3)))
    #define GetBit (a, p) (!!((a)[(p)>>3] & (1<<((p)&3))))
    

    - Unnötiger Einsatz von Makro, eine Funktion wäre wesentlich übersichtlicher.
    - Seiteneffekte durch evtl. mehrfache Auswertung von p.
    - Bricht die (ungeschriebene) Regel, dass Makros nur Großbuchstaben enthalten sollten und nicht groß/klein gemischt.

    OK, das gilt teilweise. Über Groß/Klein muß ich mir noch Gedanken machen ...

    Tim schrieb:

    Du darfst jetzt darauf herumreiten, dass ich mich unklar ausgedrückt habe...

    Lassen wir's damit gut sein.

    Tim schrieb:

    Ja, das ist fucked-up Code. Durfte ich schon oft genug wegwerfen.

    Und wenn Dir keiner das Neuschreiben von allem zahlen mag?

    Tim schrieb:

    Erleuchte uns mit Beispielen.

    Ich kann so einzelne Bits eines Bitfields als symbolisches "Funktionsargument" übergeben. C kennt keine Bits als Funktionsargument. Sehr praktisch, wenn man zwar gleiche Hardwarefunktionen hat, sie aber je nach Projekt auf unterschiedlichen Pins eines Controllers braucht. Ich versuche mich gerade daran, die ganzen Hardwareabhängigkeiten in Makros zu packen, so daß ich das letztlich über defs und include guards schalte, aber das funzt noch nicht so wie gewünscht :(. Ohne Makros wär' das aber nichtmal im Ansatz möglich.



  • Tim schrieb:

    Naja, gibt man halt Element, Größe des Elements und Offset an. Nicht wirklich tragisch.

    nicht tragisch, aber doof. warum alles immer neu schreiben, wenn macros dir diese arbeit abnehmen können? zudem bieten die makros ein intuitiv nutzbares interface u.a. wegen dieser (simulierten) referenzen. ich setze 'nen ähnlichen code ein und kann sagen, dass er noch niemals probleme gemacht hat. ich weiss nicht, woher der dieser schlechte ruf von makros kommt. möglicherweise durch high-level programmierer, deren sprachen keine macros kennen. klar, makros sind bloss einfache textersetzungen, aber trotzdem (oder deshalb?) ein werkzeug, dass sehr mächtig sein kann.

    btw, hier im c-forum hat unser allseits verehrter power-user 'net' ein/zwei postings mit einer makro-implementation von linked lists hinterlassen (such mal nach CONTAINING_RECORD). damit kann man wunderbar queues, stacks, trees usw. bauen, die super-performant sind. wenn du's mal mit irgendwelchen netzwerk-treibern und protokollen o.ä. zu tun hast, die pakete in echtzeit durch die gegend schubsen müssen, wirst du sie lieben.
    🙂



  • pointercrash() schrieb:

    Tim schrieb:

    Ja, das ist fucked-up Code. Durfte ich schon oft genug wegwerfen.

    Und wenn Dir keiner das Neuschreiben von allem zahlen mag?

    Dann nehme ich nicht an. Aber erst würde ich meinem(?) Chef klarmachen, dass die Folgekosten einer Flickschusterei wohl höher sind und eventuelle Zertifizierungen/Ähnliches davon abhängen könnten, etc. pp.

    pointercrash() schrieb:

    Ich kann so einzelne Bits eines Bitfields als symbolisches "Funktionsargument" übergeben. C kennt keine Bits als Funktionsargument. Sehr praktisch, wenn man zwar gleiche Hardwarefunktionen hat, sie aber je nach Projekt auf unterschiedlichen Pins eines Controllers braucht. Ich versuche mich gerade daran, die ganzen Hardwareabhängigkeiten in Makros zu packen, so daß ich das letztlich über defs und include guards schalte, aber das funzt noch nicht so wie gewünscht :(. Ohne Makros wär' das aber nichtmal im Ansatz möglich.

    Erklär bitte mal noch etwa genauer, bin mir nicht sicher ob ich dich recht verstehe.



  • makros forever! schrieb:

    Tim schrieb:

    Naja, gibt man halt Element, Größe des Elements und Offset an. Nicht wirklich tragisch.

    nicht tragisch, aber doof. warum alles immer neu schreiben, wenn macros dir diese arbeit abnehmen können?

    Ja, ich gestehe. Hier ist das Makro nicht unpassend.

    makros forever! schrieb:

    ich weiss nicht, woher der dieser schlechte ruf von makros kommt.

    Er kommt z.B. von diesen GetBit/SetBit-Makros, bzw. der schlechten Umsetzung derer.



  • Tim schrieb:

    Erklär bitte mal noch etwa genauer, bin mir nicht sicher ob ich dich recht verstehe.

    struct bit_def {
    		char	b0:1;
    		char	b1:1;
    		char	b2:1;
    		char	b3:1;
    		char	b4:1;
    		char	b5:1;
    		char	b6:1;
    		char	b7:1;
    };
    union byte_def{
    	struct bit_def bit;
    	char	byte;
    };
    
    union byte_def switches_union;
    #define		switches		switches_union.byte
    #define		sw0				switches_union.bit.b0
    #define		sw1				switches_union.bit.b1
    
    #define		startbutton			p5_3	// ist auch ein Bitdefine Port 5, Bit 3
    #define		stopbutton			p4_5	// ist auch ein Bitdefine
    
    #define	KEYPOLL(src0, src1, targ0, targ1) { \
    		targ0 = src0; targ1 = src1; }
    
    // -------- ...
    

    So, und jetzt probier' mal ein

    void KeyPoll(startbutton, stopbutton,sw0,sw1);
    

    oder ein

    KEYPOLL(startbutton, stopbutton, sw0 , sw1)
    

    Welches könnte funzen? 😉

    Ist jetzt klar, wie schön das ist? Egal, wohin der Entwickler die Pins gelegt hat, KEYPOLL sammelt sie mir so ein, wie ich sie weiterverarbeiten kann, ohne auch nur eine Zeile ändern zu müssen. So Tim, versuch' das mal mit "echten" Funktionen :p



  • ein weiteres nettes beispiel für den sinnvollen einsatz von macros ist die 'protothreads' library. da wird 'local continuation' mit macros implementiert, um cooperatives multitasking zu machen: http://www.sics.se/~adam/dunkels05using.pdf
    🙂



  • Da hat's bei mir sofort geklingelt, mit den "Protothreads" hat der Typ ein komplettes OS http://www.sics.se/contiki/ zusammengebastelt. Der C64- Port hat auf meinem C128 tatsächlich funktioniert 😃



  • und das sollte auch nicht unerwähnt bleiben: http://sglib.sourceforge.net/
    besteht zu 95% aus makros.
    🙂



  • CStoll schrieb:

    (und auf diese Weise erreicht man über die entsprechenden Verrenkungen ein Verhalten, das man durchaus als "call by reference" ansehen könnte)

    wieso verrenkung, das ist doch standard vorgehen in c.
    oder etwa nicht 😉



  • Und während Timmy- Bob darüber nachdenkt, wie man die Welt von Macros befreien könnte :p , hat Supertimmy die ultimative Funktion gefunden, wie man die Welt von der Ausstrahlung der "Waltons" befreien kann.
    Juhuuuu! 😃


Anmelden zum Antworten