Adreßoperator



  • 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! 😃



  • Mal was anderes. Warum funktioniert das hier eigentlich :

    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;
    };
    

    Was wird den hier gemacht und warum darf man da ein ":" in die Variablendeklaration schreiben ?
    Wenn ich

    char a:1;
    

    schreibe erlaubt der Compiler mir das ja auch nicht.

    Kann mir einer erklären warum 1. das hier geht, 2.was da eigentlich passiert ( also nur bei dem struct und den Variablen).



  • Das nennt sich "Bitfeld" und teilt einen (in diesem Fall) char in einzelne Bits auf, die du getrennt ansprechen kannst. Intern wird der Zugriff wohl wieder auf & und | mit geeigneten Masken umgerechnet.

    (und ja, das geht nur für struct-Elemente - und nur für ganzzahlige Build-in Typen ("mystruct v:1;" oder "double v:1;" ist nicht erlaubt))



  • CStoll schrieb:

    ... die du getrennt ansprechen kannst.

    jo.
    Bitfeld: 11111101

    Guten morgen Bit0 siehst gut aus heute, du hast eine positive Ausstrahlung.
    Guten morgen Bit1, was ist denn mit dir los, du machst so einen negativen.
    Guten morgen Bit2, usw.
    🙂



  • Aha ok cool, muss ich mal mit rumspielen. thx für die Infos



  • CStoll schrieb:

    Das nennt sich "Bitfeld" ... Intern wird der Zugriff wohl wieder auf & und | mit geeigneten Masken umgerechnet.

    Da muß ich widersprechen, eigentlich lösen alle besseren Embedded- Compiler solche Konstrukte in effektive Bit- Maschinenbefehle auf. 🙂



  • übrigens muss nicht immer eine 1 hinter dem doppelpunkt sein, auch grössere werte sind erlaubt (maximal bis zur anzahl bits des basistyps). bitfields sind eine art kompressionstechnik um mehrere kleine variablen zusammenzufassen und damit speicher zu sparen. bitfields sind weder dazu geeignet, noch wurden sie dazu erfunden, auf einzelne bits einer variablen zuzugreifen.
    🙂



  • also lediglich dafür gedacht um Speicherplatz zu sparen ? Is ja langweilig 😞



  • bitfield-freak schrieb:

    bitfields sind weder dazu geeignet, noch wurden sie dazu erfunden, auf einzelne bits einer variablen zuzugreifen. 🙂

    Mag sein, daß es nicht so gedacht und/oder spezifiziert ist, in der Praxis ist es aber so implementiert, wie ich das kenne. Wie anders sollte man einen µC so programmieren, der via SFR- Bits so einzelne Funktionen bitweise an- und abschaltet?


Anmelden zum Antworten