Forum: Compiler & IDEs Daten aus FIFO ins Array


von Frischling (Gast)


Angehängte Dateien:

Lesenswert?

Im Anhang ist mein kläglicher Versuch, ankommende Daten(Strings) in ein 
Array zu schreiben. Ich arbeite mit einem Wiznet 5300. Senden klappt, 
nur das Reinschreiben der FIFO-Daten(Empfangen) scheitert daran die 
Daten aus dem FIFO byteweise und sinnvoll ins interne Memory vom Wiznet 
zu schreiben. Der FIFO muss immer 16-Bit-weise ausgelesen werden, 
deswegen temp0 und temp1. Die n +16-Gesichte soll die Bytes 
aneinanderschieben. Kann mir jemand einen Hinweis geben? (bitte keine 
"hier ist ein tutorial"-links). Es hakt bei payload  = 
((temp0<<m)+((temp1)<<n));

von Karl H. (kbuchegg)


Lesenswert?

Frischling schrieb:
> Im Anhang ist mein kläglicher Versuch, ankommende Daten(Strings) in ein
> Array zu schreiben.

Da ist schon mal das erste Problem.
Woher weißt du, wann der String zu Ende ist? *payload kann ja wohl nicht 
die Steuerung der Schleife übernehmen, denn in payload kommt ja das 
Ergebnis rein. Wie willst du daber das Ergebnis befragen, wenn du die 
Werte noch gar nicht hast? Das kann also so nicht stimmen.

Zum zweiten ist payload ein Array. Man kann damit natürlich über 
Pointer-Syntax zugreifen. Aber eigentlich ist das recht witzlos. WEnn 
etwas ein Array ist, dann behandle es auch als Array - ok, nicht immer, 
aber an dieser Stelle ist es ganz sicher die einfachste Variante. Mach 
dir eine index-Variable, mit der indizierst du in das Array
   payload[index] = ....
und erhöhst den index nach jedem Zeichen.
Man muss das nicht komplizierter machen als notwendig.


> Es hakt bei payload = ((temp0<<m)+((temp1)<<n));

Darüber breiten wir mal den Mantel des Schweigens. Das ist auf so vielen 
Ebenen falsch, dass es mit dem Hinweis auf ein Tutorial nicht getan 
wäre.

Benutze Array-Index-Syntax wenn du mit Pointern auf Kriegsfuss stehst 
und das Problem ist keines mehr.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Quelltext als in einer PDF-Datei versteckten Screenshotausschnitt 
unterzubringen ist eine ganz tolle Idee.

Im übrigen ist auch die Bestimmung der Größe von "payload"
1
datasize = (udphead & 0xFF000000);
2
char payload [datasize];

ganz sicher nicht das, was Du erreichen willst. Damit ist nämlich 
payload entweder 0 oder aber mindestens 16 MBytes groß.

von Kaj (Gast)


Lesenswert?

Tu dir selbst einen Gefallen und streich das
1
goto

Wenn du ein goto brauchst, dann stimmt was mit deiner Programmstruktur 
nicht!

Meiner Meinung nach gibt es nur drei Einsatzgebiete für goto:
1. Kernel-Programmierung (da ist es sogar erwünscht!)
2. Assembler
3. Windows Batch-Scripte

In allen sonstigen Anwendungsfällen hat goto nichts zu suchen, es sei 
denn, du legst keinerlei Wert auf strukturierte Programmierung.

Grüße

von Rolf Magnus (Gast)


Lesenswert?

Kaj schrieb:
> Tu dir selbst einen Gefallen und streich dasgoto
>
> Wenn du ein goto brauchst, dann stimmt was mit deiner Programmstruktur
> nicht!
>
> Meiner Meinung nach gibt es nur drei Einsatzgebiete für goto:
> 1. Kernel-Programmierung (da ist es sogar erwünscht!)

Und was macht der Kernel so besonderes mit goto, das deiner Meinung nach 
niemals je einem anderen C-Programm nützlich sein könnte?

> In allen sonstigen Anwendungsfällen hat goto nichts zu suchen, es sei
> denn, du legst keinerlei Wert auf strukturierte Programmierung.

Es gibt schon sinnvolle Einsatzmöglichkeiten, gerade um den Code besser 
zu strukturieren. Das sind aber nicht viele. Im Prinzip nur zwei: 
Fehlerhandling und die Möglichkeit aus einer Schleife mehr als eine 
Ebene rauszuspringen, da break leider immer nur eine Ebene weit geht.

von Kaj (Gast)


Lesenswert?

Rolf Magnus schrieb:
> gerade um den Code besser
> zu strukturieren

Rolf Magnus schrieb:
> die Möglichkeit aus einer Schleife mehr als eine
> Ebene rauszuspringen

Und du kannst nicht nur über mehrere Schleifenebenen springen...
Mit goto hast du die absolut wunderbare Möglichkeit einen Mischmasch aus 
PAP, NSD und sonstwas zu schaffen. Tolle strukturierung ;)

Rolf Magnus schrieb:
> Und was macht der Kernel so besonderes mit goto, das deiner Meinung nach
> niemals je einem anderen C-Programm nützlich sein könnte?

In der (Linux-) Kernel- und Treiberprogrammierung wird mehr Wert auf 
performanten Code gelegt.

Beispiel:
Ein Treiber fordert Speicher für drei Variablen an. Wenn das alozieren 
von Speicher für nur eine Variable scheitert, muss der Vorgang 
abgebrochen und der bereits gewährte Speicher wieder freigegeben werden.
1
// ohne goto
2
if(register_chardev(...)not failed)
3
{
4
  if(request_region(...) failed)
5
  {
6
    unregister_chardevv(...);
7
    return -EIO;
8
  }
9
  if(request_irq(...) failed)
10
  {
11
    free_region(...);
12
    unregister_chardev(...);
13
    return -EIO;
14
  }
15
  return 0; //success
16
}
17
return -EIO;
18
19
//gleicher code mit goto
20
if(register_chardev(...) not failed)
21
{
22
  if(request_region(...) failed)
23
    goto out_region;
24
  if(request_irq(...) failed)
25
    goto out_irq
26
  return 0; //success
27
}
28
else
29
{
30
  goto out;
31
}
32
out_irq:
33
  free_region(...);
34
out_region:
35
  unregister_chardev(...);
36
out:
37
  return -EIO;
Das ist (abgesehen von den weggelassenen argumenten) orginal code aus 
dem linux-kernel / linux-treibern.


Natürlich ist es wieder eine Frage der eigenen Überzeugung:
goto or not goto, thats the question.

Aber ich sehe es mal so:
Es gibt mind. einen verdammt guten Grund, weshalb goto so verrufen ist:
Spaghetti-Code lässt grüßen! ;)

Wer es schaft mit goto wirklich gut und sauber strukturierten code zu 
schreiben, an dem dann auch mehrere andere Programmiere nichts 
auszusetzen haben, vor dem ziehe ich meinen Hut! (Auch wenn ich mir dann 
erst einen Hut kaufen muss :D )
Allerdings dürfte das auf die wenigsten Programmiere zutreffen.

Grüße

von Rolf Magnus (Gast)


Lesenswert?

Kaj schrieb:
> Rolf Magnus schrieb:
>> die Möglichkeit aus einer Schleife mehr als eine
>> Ebene rauszuspringen
>
> Und du kannst nicht nur über mehrere Schleifenebenen springen...
> Mit goto hast du die absolut wunderbare Möglichkeit einen Mischmasch aus
> PAP, NSD und sonstwas zu schaffen. Tolle strukturierung ;)

Daß man das kann habe ich nie bestritten. Mit vielen Sprachmitteln 
kann man Unsinn treiben. Deshalb muß man sie aber nicht gleich komplett 
verbannen. Man kann auch mit einem Hammer jemandem den Schädel 
einschlagen, und trotzdem wird er gerne und erfolgreich genutzt, um 
Nägel in Wände zu bekomnmen.

> Rolf Magnus schrieb:
>> Und was macht der Kernel so besonderes mit goto, das deiner Meinung nach
>> niemals je einem anderen C-Programm nützlich sein könnte?
>
> In der (Linux-) Kernel- und Treiberprogrammierung wird mehr Wert auf
> performanten Code gelegt.
>
> Beispiel:
> Ein Treiber fordert Speicher für drei Variablen an. Wenn das alozieren
> von Speicher für nur eine Variable scheitert, muss der Vorgang
> abgebrochen und der bereits gewährte Speicher wieder freigegeben werden.

Exakt das meinte ich mit der Fehlerbehandlung, bei der goto nützlich 
ist. Das ist es aber auch außerhalb des Kernels, und zwar nicht primär 
aus Gründen der Peformanz, sondern der Übersichtlichkeit.
Variante 1 deines Beispiels beinhaltet Code-Duplizierung, die sehr 
fehleranfällig ist. Außerdem ist die Fehlerbehandlung kreuz und quer mit 
dem Code vermischt, während sie bei der goto-Variante schön sauber 
getrennt ist. Ich empfinde das durchaus als besser strukturiert.

> Wer es schaft mit goto wirklich gut und sauber strukturierten code zu
> schreiben, an dem dann auch mehrere andere Programmiere nichts
> auszusetzen haben, vor dem ziehe ich meinen Hut! (Auch wenn ich mir dann
> erst einen Hut kaufen muss :D )
> Allerdings dürfte das auf die wenigsten Programmiere zutreffen.

Eigentlich ist es gar nicht so schwer. Es ist halt nur noch leichter, 
mit goto Spaghetti-Code zu schreiben. ;-)

von Kaj (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Es ist halt nur noch leichter,
> mit goto Spaghetti-Code zu schreiben. ;-)
Genau deswegen ist es ja auch so verrufen ;)
Ich lass aufjedenfall meine fingerchen von goto, weil es auch ohne sehr 
gut geht... und weil mich jeder Programmierer den ich kenne für den 
einsatz von goto verprügeln würde. :D
Wenn ich an einer Stelle bin, wo ich mir denke "ach, ein goto wäre 
eigentlich ganz schön...", dann überdenk ich nochmal meine 
Programmstruktur, baue um, und dann geht es auch ohne goto.

Spätestens wenn noch andere auf den Code gucken oder damit arbeiten 
müssen, hat sich das schon so gut wie erledigt. Und da gibt es noch mehr 
Beispiele an Programmierpraktiken (in C/C++) die zwar ganz toll sind, 
aber nicht effektiv angewand werden können, weil mehr als nur eine 
Person mit dem Code arbeiten muss.

Aber wie ich oben schon geschrieben habe:
> Natürlich ist es wieder eine Frage der eigenen Überzeugung:
> goto or not goto, thats the question.
So schön die Vorzüge auch sind, das K.O.-Kriterium "Spaghetti-Code" 
überwiegt meiner Meinung einfach.

An den TO:
Ein bisschen mehr code als nur der Screenshot-Schnipsel wäre schon 
hilfreich.


In diesem Sinne, schönen Mittwoch
Grüße

von Oliver (Gast)


Lesenswert?

Kaj schrieb:
> Ich lass aufjedenfall meine fingerchen von goto, weil es auch ohne sehr
> gut geht...

aber nur, weil die freundlichen Sprachdesigner die gotos per 
setjmp/lonjmp oder im OOP per try/catch verstecken. Ohne geht es halt 
nicht immer.

Oliver

von Karl H. (kbuchegg)


Lesenswert?

Nichts desto trotz würde ich den Rat an einen Anfänger unterschreiben, 
die Finger von goto zu lassen.

Das die Könner goto sinnvoll einsetzen können, wird wohl niemand 
abstreiten. Ein Anfänger ist aber kein Könner. Dafür setzen Anfänger 
einen goto für alles mögliche ein, wo ein goto sicher nicht sinnvoll 
ist.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Kaj schrieb:
> Meiner Meinung nach gibt es nur drei Einsatzgebiete für goto:
> 1. Kernel-Programmierung (da ist es sogar erwünscht!)
> 2. Assembler
> 3. Windows Batch-Scripte

und

4. Generierter Code

Beispielsweise verwendet GCC goto in auto-generiertem C-Code, der 
während des GCC-Builds aus Maschinenbeschreibungen (md) erzeugt wird. 
Ansonsten sähe man da Verschachtelungstiefen von mehreren 100 oder gar 
1000 if-then-else.

Hier ein Beispiel für eine solche Datei mit ca 70000 Zeilen:

http://www.open64.net/doc/d3/d30/kg_09_09fe_2gnu_2i386_2insn-recog_8c-source.html


Zudem macht goto die Wiederverwendung von Code-Blöcken einfacher, 
beispielsweise in
1
if (a)
2
{
3
   if (b)
4
      BLOCK1;
5
   else
6
      BLOCK2;
7
}
8
else if (c)
9
  BLOCK2;

Zwar kann man das mehrfache Auftauchen von Blöcken (hier BLOCK2) durch 
Umformulierung der if-Bedingungen vermeiden, dadurch werden aber die 
if-Bedingungen komplizierter, und es müssen mehrfach ähnliche 
Teilausdrücke in den if-Abfragen getätigt werden.  Für das kleine 
Beispiel ist die Umformulierung zwar einfach, für die große, verlinkte 
Datei ist eine Umformulierung aber weder zielführend noch hilfreich. 
goto ist dort eindeutig die beste und überlegen Lösung.

von Kaj (Gast)


Lesenswert?

Johann L. schrieb:
> 4. Generierter Code
Naja, meine Aussage war auf "handgeschriebenen" code bezogen. ;)

Grüße

von Rolf Magnus (Gast)


Lesenswert?

Karl Heinz schrieb:
> Nichts desto trotz würde ich den Rat an einen Anfänger unterschreiben,
> die Finger von goto zu lassen.
>
> Das die Könner goto sinnvoll einsetzen können, wird wohl niemand
> abstreiten. Ein Anfänger ist aber kein Könner. Dafür setzen Anfänger
> einen goto für alles mögliche ein, wo ein goto sicher nicht sinnvoll
> ist.

Sehe ich auch so. So wird's aber meist nicht verkauft, sondern eher so: 
Goto entstammt der Hölle und wurde vom Teufel geschickt, um deinen Code 
zu zerstören, also setze es blos niemals im Leben ein.
Deshalb haben auch die meisten Könner panische Angst vor goto, wie man 
ja hier ganz gut sehen kann.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.