Simon schrieb:> // geht nicht:
"Geht nicht" ist im allgemeinen keine gute Beschreibung für ein Problem.
Auch ein erfahrener Programmierer sieht mitunter nicht sofort das
Problem in einem Programm, das "nicht geht". Deshalb sollte man
mindestens anfügen, welche Fehler der Compiler ausspuckt oder inwiefern
das Programm nicht/falsch funktioniert. Auch deshalb, weil je nach
Sprachversion und Plattform nicht die gleichen Spielregeln gelten.
Also ich kann auch mal nur raten, aber von dem hier gezeigten Code
stimmt das definierte Struct nicht mit dem Parameter überein wo
aufgerufen werden.
Als zweitens frage ich mich warum du cnt als 16 bit definierst aber dann
doch wieder auf einen 8 bit wert(bzw. Pointer) castest.
Noch interessanter wäre es wenn man mehr vom Code sehen würde, oder gib
uns die Prototypen von den aufzurufenden Funktionen.
Und wie schon erwähnt welchen Fehler spukt der Compiler aus. Oder lässt
sich es kompilieren ? Wenn ja wo durch merkst du das es nicht
funktioniert ?
Viele Grüße
Richi
Simon schrieb:> Tuts, wirklich bestens
Ganz gewiss nicht. bf->addr_tmp gibt es nämlich nicht.
Wenn du hier irgendeine ernsthafte Hilfe wünschst, dann fake bitte
nicht irgendwelchen Code, von dem du glaubst, dass er zu dem, mit
dem du ein Problem hast, äquivalent wäre. Schneide den problematischen
Code soweit zusammen, dass das Problem möglichst kurz und knapp übrig
bleibt und poste dann den Code, aber bitte zusammen mit der konkreten
Fehlermeldung.
Ah moment da waren mehr Fragen.
er liest schlichtweg das falsche aus, als ob er von einer falsche
adresse liest. das sizeof funzt jedoch auch bestens.
compilen geht ohne jeglicher warnung.
Der Prototyp für chksum ist
void chksum_add (const BYTE* buffer, WORD count)
Simon schrieb:> Jörg W. schrieb:>> Glaub' ich nicht.>> Tuts, wirklich bestens, ich benötige die adresse vom member eines> structs
Also, dass man mal was übersieht - und auch mal hartnäckig am Problem
vorbei schaut -, dass passiert den Besten. Mir nicht, aber Klaus. :-)
Aber glaub mir, wenn Jörg Wunsch und noch ein paar das sagen, dann ist
es höchste Zeit mal "ganz scharf" hinzu schauen. Wenn man dann noch
nichts sieht, mal ein paar Stunden schlafen oder einen schönen
Spaziergang machen. Auf jeden Fall erst aufhören, wenn der Code ohne
Fehlermeldung compiliert. Das tut er nämlich nicht.
Es ist schlicht unmöglich, dass der gezeigte Code jemals funktioniert
hat.
Du hast hier gleich mehrere Ungeschicklichkeiten begangen, die sich nun
leider zu einem Kuddel-Muddel gegen Dich vereinigen.
1. (Vermutlich) den Code nicht mit Copy&Paste eingefügt bzw.
nachträglich so bearbeitet, dass er nicht mehr kompilierbar ist.
2. Fehler nicht beschrieben. Ein ganz böses Versäumnis. Denn so kann dir
niemand helfen Dir zu helfen.
3. Erkennbar einige grundlegende Mängel im Verständnis von C. Das allein
wäre nicht weiter schlimm, wenn es das einzige Problem wäre.
Versuche die Punkte 1. bis 3. in Deiner Fragestellung zu korrigieren. Es
musst nicht perfekt sein, aber das Bemühen erkennbar.
Simon schrieb:> compilen geht ohne jeglicher warnung.
Das mag unter Umständen so sein. Aber dafür kriegst Du einen Haufen
Fehlermeldungen.
Ich möchte Dich ernstlich davor warnen, auf die bisherige Art in diesem
Thread fortzufahren. Andernfalls wird Dir nicht geholfen oder Du wirst
möglicherweise mit zunehmender Härte kritisiert.
Simon schrieb:> er liest schlichtweg das falsche aus, als ob er von einer falsche> adresse liest. das sizeof funzt jedoch auch bestens.
Okay wäre noch schön zu wissen was du erwatest und was du zurück
bekommst.
Bleiben wir mal nur bei einer Zeile code.
Dieser code funktioniert tadellos, er compiled und
das errechnete Ergebnis stimmt.
Das gilt sowohl für das sizeof() als auch die übergebene Adresse
von &tmp_cnt
1
uint32_t tmp_cnt;
2
tmp_cnt = 0x1122AAEE;
3
chksum_add((uint8_t *)&tmp_cnt, sizeof(tmp_cnt));
Meine Frage ist hier einfach warum das bei einem struct nicht mehr der
fall ist.
Es ist bekanntlich leichter, den verlorenen Schlüssel unter der
Strassenlaterne zu suchen, als in jener dunklen Ecke, in der man ihn
verlor. Aber finden wird man ihn da nicht.
Simon schrieb:> Meine Frage ist hier einfach warum das bei einem struct nicht mehr der> fall ist.
Keine Ahnung.
Vielleicht zeigt dein Pointer bf in den Wald?
Wie schon gesagt: kompletten, compilierbaren Code, der das betreffende
Verhalten zeigt.
Es ist ein Mythos, dass man alle Fehler an einer einzigen Zeile Code
festmachen kann. Oft steckt der Fehler ganz woanders, als du ihn
vermutest. Was du bist jetzt hast, ist die Zeile an der sich die
Symptome bemerkbar machen. Aber das Problem kann auch ganz woanders
sitzen.
Simon schrieb:> Bleiben wir mal nur bei einer Zeile code.
Das ist noch so eine Ungeschicklichkeit. Nun gut. Ich habe Dich gewarnt.
Mehr kann man nicht tun.
WIR sind diejenigen die Du fragst und WIR bestimmen wie und wo es
langgeht.
Wenn Du darauf bestehst, uns die Richtung vorzugeben, dann löse das
Problem auch alleine. Wir wissen selbst wie man Fehler sucht und bei
Fragen vorgeht.
Dazu brauchen wir keine Belehrung von Dir. Es ist gerade umgekehrt.
Naja ich geb jetzt mal auf hier für Hirngespinste hab ich keine Zeit
bzw. mag keine Zeit investiern. Entwerder Code oder keine Hilfe mehr, es
wird ja hier nicht mal auf ernst gemeinte fragen geantwortet.
Jeder der hier versucht gutes zu leisten soll es lassen da, der TE nicht
wirklich kooperiert!!!!!!!!!!
Karl H. schrieb:> Keine Ahnung.> Vielleicht zeigt dein Pointer bf in den Wald?
Ich hab den code mal durch gesteppt, ne ansich auch nicht, merkwürdig.
Inzwischen glaube ich das (uint8_t *)&bf->cnt einfach korrekt ist
Simon schrieb:> Inzwischen glaube ich das (uint8_t *)&bf->cnt einfach korrekt ist
Ist es auch.
Wie gesagt: Symptom - Ursache.
Du siehst das Symptom. Die Ursache steckt woanders.
Klaus, relax,
mir ist schon klar das mir hier keiner Helfen kann für code den ich hier
nicht poste, mir ging es einfach nur darum ob das casten sowie die frage
nach der adresse so korrekt ist, ich war mir einfach unsicher
Simon schrieb:> Klaus, relax,
Was lässt Dich annehmen, dass ich mich irgendwie aufrege? Das gewöhne
ich mir gerade mit einigem Erfolg ab.
Helf' ich nicht Dir, dann dem Nächsten der geschickter fragt.
@Simon
Setze 'bitte' erst mal deine Funktionsklammern richtig;
dann setz dich mit der Frage hin, warum der Compiler
da stehen bleibt wo er steht, wenn er noch stehen bleibt;
ich denke dass dein Contsruct gut aussieht, aber du vermasselst
es mit der Klammer.
;-)
Simon schrieb:> void chksum_add (const BYTE* buffer, WORD count)Simon schrieb:> chksum_add((uint8_t *)&tmp_cnt, sizeof(tmp_cnt));
Kleine Zwischenfrage an die C-Experten: Wäre hier ein void-Pointer nicht
angebrachter?
Simon schrieb:> Bleiben wir mal nur bei einer Zeile code.>> Dieser code funktioniert tadellos, er compiled und> das errechnete Ergebnis stimmt.>> Das gilt sowohl für das sizeof() als auch die übergebene Adresse> von &tmp_cnt>>
/*Glaskugel an:*/
Das wird daran liegen weil der Code im Funktionsrumpf steckt auf dessen
Adressen er zugreift
>>> Meine Frage ist hier einfach warum das bei einem struct nicht mehr der> fall ist.>>
Weil das Struct irgendwo liegen kann, wir wissen es nicht wo es liegt,
auch die Glaskugel weiss es nicht, hast du dein struct in der header
oder code file und hast du das eingebunden oder nicht, wir wissen es
nicht.
Zumal der Code im Eröffnungspost auch nicht vollständig ist;
kein #include
kein #define
kein abgeschlossener Funktionsrumpf
aber umgeschriebener code aus einem Funktionsrumpf,
der funktioniert, auf ein Struct irgendwo im Projekt.
und der gleich zweimal im noch offenen Funktionsrumpf hängt.
mhm.
Wenn man dir sagt, "Super, der Struct Code müsste eigentlich gehen,
aber es läuft dann doch nicht bei dir, ist dir damit nicht geholfen
auf deine Frage geantwortet zu haben.
So wie der Code da steht, kann er nicht laufen
a) die Funktion "void fb_buffer_write_stop(BUFFER_STATUS *bf)"
hat einen Anfang aber kein Ende.
b) in der Funktion wird auf ein struct verwiesen, dass nicht includiert
wurde
c) es ist ein Unterschied ob du jetzt den Code an und für sich bestätigt
haben willst oder dir es um die Funktionalität geht. Denn, du siehst
jetzt die Codezeile mit deinem struct Verweis, hast du alles dazu auch
richtig includiert, zumindest fehlt die Endklammer schon mal von der
Funktion "void fb_buffer_write_stop(BUFFER_STATUS *bf)".
> Du siehst das Symptom. Die Ursache steckt woanders
So ist es leider in deinem Fall.
Simon schrieb:> Dieser code funktioniert tadellos, er compiled und> das errechnete Ergebnis stimmt.
wie gesagt, dann ist es aber nicht der Code der da steht.
Simon schrieb:> bf->addr_tmp += sizeof(bf->cnt);
abgesehen davon, dass es das Member nicht gibt, sieht das komisch aus.
Frage: Du weißt, was Alignement ist und was Padding Bytes sind?
Vielleicht steht an der Pufferadresse nur was anderes als du vermutest,
weil der Puffer vorher anders Gefüllt wurde.
Beispiel:
1
typedefstructA{
2
uint8_ta;
3
uint16_tb;
4
uint8_tc;
5
uint32_td;
6
}A;
sieht mit großer wahrscheinlichkeit so aus:
1
typedefstructA{
2
uint8_ta;
3
uint8_t_pad0;
4
uint16_tb;
5
uint8_tc;
6
uint8_t_pad1;
7
uint8_t_pad2;
8
uint8_t_pad3;
9
uint32_td;
10
}A;
wenn du jetzt einen Puffer bekommst, der eigentlich eine A* ist und du
so ausließt
Vlad Tepesch, vielen Dank für die Ausführliche Erklärung.
Ich erhöhe hier keinen pointer der dann natürlich je nach pading in
einen falschen adressbereich gehen würde.
Allerdings habe ich da mal ne Frage, ich versuche es mal zu beschreiben.
1
tmp_cnt = 0x1122AAEE;
2
bf->cnt = tmp_cnt;
3
4
ptr = (uint8_t*)&bf->cnt; // 0xA00088E0
5
eins = *ptr++; // 0xA00088E1
6
zwei = *ptr++; // 0xA00088E2
7
drei = *ptr++; // 0xA00088E3
8
vier = *ptr;
9
10
ptr = (uint8_t*)&tmp_cnt; // 0xA001FED4
11
eins = *ptr++; //0xA001FED5
12
zwei = *ptr++; //0xA001FED6
13
drei = *ptr++; //0xA001FED7
14
vier = *ptr;
Der code ist getestet und funktioniert, das Ergebnis in den Variablen
ist das selbe.
egal wie ich es also drehe der pointer zeigt auf die anfangsadresse und
lässt sich genauso erhöhen wie eine normale Variable egal ob er
bestandteil einer structure ist oder nicht
Simon schrieb:> Allerdings habe ich da mal ne Frage
Schade, dass wir die Frage nicht kennen. Du willst vermutlich die
Funktionsweise von Pointerarithmetic, alignement und struct padding
wissen.
Pointerarithmetik:
1) Einem Pointer ist es egal, ob er in's nirvana oder sonstwohin zeigt.
Das darf er, weil er nur eine Zahl ist. Es ist nur nicht erlaubt einen
Pointer ins Nirvana zu dereferenzieren, da dies zu zugriffen auf
ungültige oder unbekannte Speicherstellen führt.
2) Pointer haben eine "einheit". Sie können nur um die grösse ihres
darunterliegenden Datentyps erhöt oder verringert werden:
((uint32_t*)4)+1 entspricht &((uint32_t*)4)[1] entspricht (uint32_t*)8
entspricht (uint32_t*)(((uint8_t*)4)+sizeof(uint32_t))
Alignement:
Ein Pointer ist Aligned, wenn... ich formuliers lieber als c code:
type* x; // ziel unbekannt
bool aligned = ( ((uintptr_t)x) % sizeof(*x) ) == 0;
Das dereferenzieren eines unaligned pointers ist erlaubt, aber
undefiniert und sollte vermiden werden, ausser es ist dem Compiler
bekannt z.B. bei packet struckts, die nicht teil des c standards sind.
Padding:
1) Vor dem ersten Member einer union oder eines structs darf es kein
Padding geben.
2) Zwischen Arrayelementen darf es kein Padding geben.
3) Zwischen struct Membern gleicher grösse darf es kein padding geben.
4) Am Ende eines Structs und zwischen Structmembern unterschiedlicher
grösse darf es padding geben.
5) Die Padding bytes sind gültige Speicherbereiche die dereferenziert
und überschrieben werden dürfen. z.B. mit memset.
Gut zu wissen:
Mit alignof kann der offset eines Structmembers bestimmt werden. Das
ermöglicht verrückte Präprozessor un c code tricks.
PS: Dein code hat ein Endiannes problem. Nutze Bitshifts oder hton.