Hallo Leute,
mir ist nicht 100%ig klar, was hier passiert:
1
voidCommand(unit8_tcom[]){
2
3
#define Addr (*(uint16_t*)&com[2]) // Was passiert hier genau?
4
5
...
6
7
}
Der Funktion Command wird ein uint8_t-Array mit 8 Elementen übergeben.
Soll dann die Adresse des dritten Array-Elementes als 16 Bit Pointer
interpretiert werden, ähnlich wie hier?
http://www.proggen.org/doku.php?id=c:cast#vorsicht_beim_casten1
Was bedeutet der erste Stern?
Danke im Voraus!
Bastian schrieb:> Was bedeutet der erste Stern?
Dass du ein C Handbuch brauchst. ;-)
Der linke Stern dereferenziert, der rechte macht einen Pointer aus dem
Typ im Cast.
Oh, ich glaube jetzt hat es geschnackelt!
Mit dem ersten * greife ich ja auf den Inhalt des neu gecasteten
16bit-Pointers zu und damit auf Byte 3 und 4 des Arrays als 16bit-Zahl?!
A. K. schrieb:> Dass du ein C Handbuch brauchst. ;-)
Bin dabei, bin dabei. Aber du verstehst sich, das für einen Anfänger so
ein Ausdruck erst einmal schwierig ist. An was man sich da alles
erinnern muss ;-)
Bastian schrieb:> Aber du verstehst sich, das für einen Anfänger so> ein Ausdruck erst einmal schwierig ist.
Yep. C ist nichts für Ästheten, und sowas schon garnicht.
Bastian schrieb:> Oh nein, schon wieder was zum nachlesen ;-)
Aber das findest du im C Handbuch nicht.
>#define Addr (*(uint16_t*)&com[2])
Super -so eine einfache und klare Struktur! Da erkennt man auf den
ersten
Blick, wofür das gut ist.....
(Der Beitrag kann geringe Spuren von Ironie enthalten)
Warum tut sich ein Mensch solchen Rotz an?
Das ist Masochismus in Reinkultur.
Von rechts nach links lesen:
com Ist hier foo
[2] Das 3. Element von foo.
& davon die Adresse nehmen und ...
(uint16_t*) ... als Zeiger auf einen uint16_t ansehen (der
bei 0x33 beginnt und 2 Byte groß ist)
* ... und diesen dereferenzieren.
=> Ergebnis 0x4433
Wie man sieht, ist mein PC Little Endian, weil "das kleinstwertige Byte
an der Anfangsadresse gespeichert [wird]".
Bastian schrieb:> Dachte ich mir, wohl eher im µC Datenblatt?!
In der Beschreibung des Prozessors. Wenn es nicht grad ein 8-Bit Typ
ist, denn denen ist das üblicherweise egal.
Extrem Entzückter schrieb:> Das ist Masochismus in Reinkultur.
Du bis aber leicht zu beeindrucken. Schau mal hier rein:
http://www.ioccc.org/
Eines der harmloseren Beispiele als Anhang. Das Programm tut durchaus
etwas sinnvolles und wird von einem (BSD) C-Compiler sauber übersetzt.
Bastian schrieb:> nicht alles zu Null?
Weshalb? Präfix Operatoren wie *, & und Cast haben Vorrang vor <<, und
der wiederum vor |. Einzig die Klammern vom Cast sind als integraler
Teil ebendieses Operator unverzichtbar.
A. K. schrieb:> Weshalb? Präfix Operatoren wie * und Cast haben Vorrang vor <<.
Ich meinte, wenn ich eine 16bit-Zahl um 16 Stellen nach links
verschiebe.
Ich dachte die "neuen" Stellen werden mit Nullen aufgefüllt!?
Extrem Entzückter schrieb:> Warum tut sich ein Mensch solchen Rotz an?> Das ist Masochismus in Reinkultur.
Du scheinst "bessere" Programmiersprachen zu kennenn. Welches wäre denn
deine bevorzugte Programmier-Sprache, welche automatisch (oder mit
entsprechenden Befehl) selbiges auf die gegebene Datenstruktur ausführt?
Könntest du das mal aus Ausdruck hinschreiben? Dann könnten wir mal
ästhetische Vergleiche durchführen.
Bastian schrieb:> Ich dachte die "neuen" Stellen werden mit Nullen aufgefüllt!?
Und? Ok, auf einem 8/16-Bitter wird es wirklich zu 0, aber das hat
nichts mit den Klammern zu tun. Das Statement stammt offensichtlich aus
einer 32- oder 64-Bit Umgebung.
A. K. schrieb:> Und? Ok, auf einem 8/16-Bitter wird es wirklich zu 0, aber das hat> nichts mit den Klammern zu tun.
Ja, das meint ich. Was das woll soll?
Bastian schrieb:> Ja, das meint ich. Was das woll soll?
Das soll heissen, dass nicht jeder Code, der für einen 32-Bit Prozessor
geschrieben wurde, auch auf einem 16-Bitter läuft.
Wegstabenverbuchsler
>Du scheinst "bessere" Programmiersprachen zu kennenn.
Naja -zumindest welche, für deren Syntaxübersetzung einer Zeile nicht
Stunden und mehrere C-Bücher braucht. Das sieht man ja hier gerade,
wie die obige Zeile von mehreren Leuten jeweils anders interpretiert
wird.
>Welches wäre denn>deine bevorzugte Programmier-Sprache,
früher Pascal heute Lazarus oder Pure-Basic
>welche automatisch (oder mit>entsprechenden Befehl) selbiges auf die gegebene Datenstruktur ausführt?
weiß ich nicht -so eine Konstruktion habe ich noch nie gebraucht.
Bastian schrieb:> Ich meinte, wenn ich eine 16bit-Zahl um 16 Stellen nach links> verschiebe.>> Ich dachte die "neuen" Stellen werden mit Nullen aufgefüllt!?
Nein, zumindest nicht wenn sizeof(int) = 2 ist. Dann ist's undefined
behaviour (oder unspecified? die werf ich immer durcheinander).
Georg G. schrieb:> Extrem Entzückter schrieb:>> Das ist Masochismus in Reinkultur.>> Du bis aber leicht zu beeindrucken. Schau mal hier rein:> http://www.ioccc.org/>> Eines der harmloseren Beispiele als Anhang. Das Programm tut durchaus> etwas sinnvolles und wird von einem (BSD) C-Compiler sauber übersetzt.
Wir sind uns hoffentlich über zwei Dinge einig:
1.) Der IOCCC bringt schon ein paar geile Dinge hervor (ich mag
besonders die Sachen von Oscar Toledo).
2.) Niemand, der noch ganz bei Trost ist, programmiert so in einem
Industrieprojekt in dem es darum geht Geld zu verdienen.
Wegstabenverbuchsler schrieb:> Du scheinst "bessere" Programmiersprachen zu kennenn.
Nein, das ist keine Frage der Programmiersprache. Das hier gezeigte
Code-Beispiel ist aus verschiedenen Gründen (z.B. Prozessorabhängigkeit,
Lesbarkeit, Wartbarkeit) einfach grottig. Man kann in jeder Sprache
schlechten Code schreiben, auch und gerade in C. Das heißt aber nicht,
dass man es auch tun sollte.
> Welches wäre denn> deine bevorzugte Programmier-Sprache, welche automatisch (oder mit> entsprechenden Befehl) selbiges auf die gegebene Datenstruktur ausführt?
Code wird immer noch nach Anforderungen entwickelt. Die richtige Frage
lautet daher: Was ist eine sinnvolle Anforderung, die bei sauberer
Programmierung zu einem Code-Beispiel wie dem oben gezeigten führt?
Und schon wird die Luft ganz dünn. ;-)
Mark Brandis schrieb:> 2.) Niemand, der noch ganz bei Trost ist, programmiert so in einem> Industrieprojekt in dem es darum geht Geld zu verdienen.
So wie im IOCCC sicher nicht, das bedient ja auch eher die künstlerische
Ader. Das Beispiel des Threaderöffners schockiert mich ehrlich gesagt
nicht mal im Ansatz - dazu wühlt man sich durch zuviel C/C++-Code und
hat häufig nicht den Zeitrahmen, das sauberer z.B. über Unions zu lösen.
Gerade bei einer großen Codebasis kommst du dann beim Refactoren vom
Hundersten ins Tausendste.
> Wegstabenverbuchsler schrieb:>> Du scheinst "bessere" Programmiersprachen zu kennenn.>> Nein, das ist keine Frage der Programmiersprache. Das hier gezeigte> Code-Beispiel ist aus verschiedenen Gründen (z.B. Prozessorabhängigkeit,> Lesbarkeit, Wartbarkeit) einfach grottig. Man kann in jeder Sprache> schlechten Code schreiben, auch und gerade in C. Das heißt aber nicht,> dass man es auch tun sollte.
Glaube ich nur begrenzt. Ich behaupte, dass die Designer einer
Programmiersprache sehr wohl und sehr deutlich durch die Grammatik den
Programmierstil der Programmierer beinflussen! Eine moderne Sprache
stellt sich sicher auf die Mehrzahl ihrer Programmierer ein und schließt
alleine durch ihre Sprachgrammatik bereits Fehler aus.
Beispiel: die notwendige Implementierung von virtuellen Destruktoren in
rein virtuellen (abstrakten) Klassen bei C++ ist so ein Fehler, der mich
so einige Memleaks in der Vergangenheit gekostet hat - bloß weil der
Compiler einen automatischen nicht-virtuellen Destruktor für das
Interface gebaut hat und somit der Destruktor der Ableitung nicht
aufgerufen wurde... macht Java oder C-Gartenzaun (C#) mittels eigenem
Schlüsselwort besser.
>> Welches wäre denn>> deine bevorzugte Programmier-Sprache, welche automatisch (oder mit>> entsprechenden Befehl) selbiges auf die gegebene Datenstruktur ausführt?>> Code wird immer noch nach Anforderungen entwickelt. Die richtige Frage> lautet daher: Was ist eine sinnvolle Anforderung, die bei sauberer> Programmierung zu einem Code-Beispiel wie dem oben gezeigten führt?>> Und schon wird die Luft ganz dünn. ;-)
Nicht immer ist eine Anforderung, dass der Code lesbar ist. Gerade bei
Schnittstellen, deren interne Funktion nicht leicht ertestbar sein
sollen, entsteht mitunter übler Code. Oder aber wenn ein Feature schon
vorgestern fertig sein musste, der Programmierer aber erst heute davon
erfährt... :)
Weiteres Beispiel: Constraints! Wenn du also jemanden hast, der dir
keine Requirements spezifiziert, sondern praktisch das Design vorgibt
(z.B. durch Fremdcode), an den du dich halten musst, so sind das
Constraints für dich.
Und dann argumentier mal bitte von wegen Qualitäten usw. wenn das
Projekt seitens des Herstellers höchstens noch Wartungsaufwand generiert
und daher nur die gröbsten Bugs gefixt werden...
Und die ultimative Antwort auf Frage nach der Anforderung, die solchen
Code generiert: nicht '42', sondern das kleine, unscheinbare Wort
'Termindruck'...
Sicher, wenn eine Firma mit schlechtem Code leben will, der soll sie
dies tun. Dann soll sie sich aber auch gefälligst nicht beschweren, wenn
das Ergänzen von neuer Funktionalität länger dauert und somit teurer
ist.
Mark Brandis schrieb:> Sicher, wenn eine Firma mit schlechtem Code leben will, der soll> sie dies tun. Dann soll sie sich aber auch gefälligst nicht beschweren,> wenn das Ergänzen von neuer Funktionalität länger dauert und somit teurer> ist.
Na, dann erzeugen neue Funktionen neue Aufwände und die kann man
bekanntlich besser abrechnen... man wundert sich dann aber später darum,
warum die Zeitschätzungen für neue Projekte immer vollkommen (deutlich >
Faktor 2) daneben liegen...
Das Lustige daran: in der Janus-köpfigen Firmenwelt ist doch die
Time-To-Market oft das entscheidende Merkmal. Nach draußen groß auf
Qualität machen, aber dem Softwareentwickler nicht wirklich die Zeit
geben, wirklich eine qualitativ hochwertige Codebasis zu schaffen (z.B
wegen irgendwelcher anderen Projekte). Diesen Luxus hat man nicht immer.
Da schreibste halt erstmal so, dass es überhaupt funktioniert, bis du
irgendwann mal Zeit findest, das ordentlich zu machen.
Weitere Behauptung von mir: Programmierer, die nie ranzigen Code
geschrieben haben, warten bzw. erweitern oder auch nur verstehen
mussten, sollten sich sehr glücklich schätzen... denn es gibt immer
Code, der noch schlechter ist...
Johann L. schrieb:> Dann ist's undefined behaviour> (oder unspecified? die werf ich immer durcheinander).
Undefined. Ist auch besser so, denn verschiedene Implementierungen der
gleichen Architektur verhalten sich dabei u.U. unterschiedlich.
A. K. schrieb:> Undefined.
Darf ich widersprechen? K&R, Seite 189, Linkshift: "vacated bits are
0-filled", Rightshift: 0-fill wenn unsigned, nur bei signed ist es
undefiniert (0 oder das Vorzeichenbit).
Wäre es wirklich immer undefiniert, würden Bitoperationen wie "x |= (1
<< BITPOS) nicht funktionieren. Und die findet man ja wohl zu hauf.
Georg G. schrieb:> A. K. schrieb:>> Undefined.>> Darf ich widersprechen? K&R, Seite 189, Linkshift: "vacated bits are> 0-filled", Rightshift: 0-fill wenn unsigned, nur bei signed ist es> undefiniert (0 oder das Vorzeichenbit).
Darum gehts nicht.
Es geht darum, was passieren soll, wenn man um mehr Bits shifted, als
der Datentyp groß ist.
Und das ist undefined. Ich kann mich an einen Fall erinnern, in dem das
links Shiften eines 16 Bit Wertes um 16 Bits zu keiner Veränderung des
Wertes geführt hat.
Georg G. schrieb:> Darf ich widersprechen?
Nein. Es ging um die Frage, was bei N >= #Bits passiert.
Da arbeitete beispielsweise der 8086 noch Modulo 256, die Nachfolger
aber Modulo 32 (bzw. 64 bei 64-Bit Operationen). Bei N=33 gibts also
recht verschiedene Ergebnisse.
Falk Schilling schrieb:> nicht den Zeitrahmen, das sauberer z.B. über Unions zu lösen.
Union ist ohnehin kaum „sauberer“.
Sauber wäre es, mit einer Inline-Funktion die Bytes einzeln zu
schieben und zu addieren (oder zu verODERn).
Für den hier genannten Zweck (das Rauspopeln der Adresse aus dem
Bytehaufen erfolgt ja nur für ein printf(), also zu Debugzwecken)
ist das ein pragmatischer Ansatz, den man durchaus wählen kann.
Es fehlt eigentlich nur ein
1
#undef Addr
direkt nach der
Benutzung, damit niemand auf die Idee käme, den Makro anderweitig
zu missbrauchen.