Forum: Mikrocontroller und Digitale Elektronik In C aus Programm herausspringen


von Peter S. (peterson124)


Lesenswert?

Gibt es einen Befehl (bitte nur in C, da ich die Assembler Sprache nicht 
kenne), mit dem ich ungeachtet von Schleifen usw. zu einem bestimmten 
Punkt im Programm "springen" kann? Zum Beispiel, um bei bestimmen 
Bedingungen (wenn eine if-Abfrage wahr ist) wieder zum Anfang des 
Programms zu kommen und alle folgenden Befehle zu ignorieren?

Danke und LG

Peterson

von Harry L. (mysth)


Lesenswert?

Gibt es:

break

von Bimbo. (Gast)


Lesenswert?

C? Bitteschön ;):
1
asm volatile("jmp 0x00");

von leo (Gast)


Lesenswert?

Peter S. schrieb:
> Gibt es einen Befehl (bitte nur in C, da ich die Assembler Sprache
> nicht
> kenne), mit dem ich ungeachtet von Schleifen usw. zu einem bestimmten
> Punkt im Programm "springen" kann?

Im Prinzip ja, aber ...

setjmp/longjmp

leo

von Thomas K. (joshua314)


Lesenswert?

Oder ein anderer weg ist.....

Watchdog scharf machen, die einen Reset macht.
Dann

    while(1);


Der Rest kommt alleine


Gruß Thomas

von Oliver S. (oliverso)


Lesenswert?

Wie immer bei solchen Fragen heißt die Gegenfrage: Warum?

Oliver

von Manfred (Gast)


Lesenswert?

Harry L. schrieb:
> Gibt es:
> break

Mit 'break' steige ich aus einer 'while-Schleife' aus.
Ein Unterprogramm verlasse ich mit 'return'.

In beiden Fällen komme ich dahin zurück, von wo ich den Aufruf gemacht 
habe.

Die Frage nach beliebig oder zum Anfang sehe ich damit als nicht gelöst 
an. Was meint Peter eigentlich mit "Anfang des
Programms" - den Beginn der Hauptschleife?

Beitrag #5909778 wurde von einem Moderator gelöscht.
Beitrag #5909786 wurde von einem Moderator gelöscht.
Beitrag #5909788 wurde von einem Moderator gelöscht.
von NichtWichtig (Gast)


Lesenswert?

Oliver S. schrieb:
> Wie immer bei solchen Fragen heißt die Gegenfrage: Warum?
>
> Oliver

Warum willst Du das wissen?

Beantworte doch einfach die Frage.

von Wichtig (Gast)


Lesenswert?

Einfach ctrl-alt-del an den Controller senden.

von test (Gast)


Lesenswert?

NichtWichtig schrieb:
> Oliver S. schrieb:
> Wie immer bei solchen Fragen heißt die Gegenfrage: Warum?
> Oliver
>
> Warum willst Du das wissen?
>
> Beantworte doch einfach die Frage.

Warum?

Wenn man sich in einem Bereich nicht auskennt ist es unwahrscheinlich 
eine gute Lösung für ein Problem zu finden.
Meist findet man dann schlechte Lösungen (man merkt allerdings nicht das 
die Lösung schlecht ist weil man die richtigen halt nicht kennt). Und 
dieser Person dann dabei zu helfen diese schlechte Lösung umzusetzen ist 
nicht wirklich eine Hilfe.

von GEKU (Gast)


Lesenswert?

Peter S. schrieb:
> von Schleifen usw. zu einem bestimmten Punkt im Programm "springen"
> kann?

goto wird oft in Kernel-Funktionen verwendet , da man im Gegensatz zu 
break, nicht nur Schleifen verlassen kann, sondern gezielt Labels 
(mit Marken gekennzeichnet Adressen) anspringen kann.

 Mit return kann man Schleifen in einem Unterprogramm verlassen indem 
man aus dem Unterprogramm selbst aussteigt.. Im Gegensatz zu goto wird 
beim Verlassen das Stack wieder in den ursprünglichen Zustand versetzt, 
dass heisst zuvor gesicherte Register wieder hergestellt.

von Maxim B. (max182)


Lesenswert?

Peter S. schrieb:
> wieder zum Anfang des
> Programms zu kommen und alle folgenden Befehle zu ignorieren?

Dafür gibt es "Goto". Aber Verwendung von "Goto" ist nicht empfohlen.

von Karl (Gast)


Lesenswert?

Maxim B. schrieb:
> Aber Verwendung von "Goto" ist nicht empfohlen.

Genau, führt direkt in die Hölle!!!

von S. R. (svenska)


Lesenswert?

Peter S. schrieb:
> Gibt es einen Befehl (bitte nur in C, da ich die Assembler Sprache
> nicht kenne), mit dem ich ungeachtet von Schleifen usw. zu einem
> bestimmten Punkt im Programm "springen" kann?

Es ist nicht möglich, in eine andere Funktion zu springen, ohne diese 
aufzurufen. Davon abgesehen wurden setjmp/longjmp bereits genannt.

Zu guter Letzt gibt es noch eine gcc-Erweiterung, mit der man die 
Adresse eines Labels nehmen kann (void *ptr = &&labelname). Die kann man 
dann direkt anspringen (goto *ptr). Ist die Adresse außerhalb der 
aktuellen Funktion, passieren komische Dinge (kaputter Stack).

von GEKU (Gast)


Lesenswert?

Maxim B. schrieb:
> Aber Verwendung von "Goto" ist nicht empfohlen.

Mit welcher Begründung?

von Roland F. (rhf)


Lesenswert?

Hallo,
GEKU schrieb:>
> Mit welcher Begründung?

Mit dieser Frage öffnest du gerade das Tor zur Hölle.

rhf

von Yalu X. (yalu) (Moderator)


Lesenswert?

Karl schrieb:
> Maxim B. schrieb:
>> Aber Verwendung von "Goto" ist nicht empfohlen.
>
> Genau, führt direkt in die Hölle!!!

Aber nur mit Clang. Der derzeitige GCC meldet bei

1
  goto Hölle;

mehrere Fehler, so dass die Fahrt in die Hölle gar nicht erst gestartet
werden kann ;-)

Das wird sich aber sicher in einer zukünftigen Version ändern.

: Bearbeitet durch Moderator
von F. F. (foldi)


Lesenswert?

Karl schrieb:
> Genau, führt direkt in die Hölle!!!

Ja, auf einem µC schon, aber in anderen Programmen, auf dem PC, ist das 
doch sicher noch üblich, wenn das auch als schlechter Stil angesehen 
wird.
Der Zweck heiligt immer die Mittel.

1
Zur Programmierung empfiehlt es sich, die break-, continue- und return-Anweisung der goto-Anweisung vorzuziehen, wann immer dies möglich ist. Da die break-Anweisung nur eine Ebene der Schleife beendet, ist möglicherweise eine goto-Anweisung erforderlich, um die Schleife aus einer tief verschachtelten Schleife heraus zu beenden.

Wenn es sich aber um Programmierung von Mikrocontrollern handelt, sollte 
man so was tunlichst vermeiden.

: Bearbeitet durch User
von F. F. (foldi)


Lesenswert?

Yalu X. schrieb:
> Aber nur mit Clang. Der derzeitige GCC meldet bei
>
>   goto Hölle;
>
> mehrere Fehler, so dass die Fahrt in die Hölle gar nicht erst gestartet
> werden kann ;-)

... und landet dann bei Wolfgang Petri.
Hölle, Hölle, Hölle.

von GEKU (Gast)


Lesenswert?

Wenn man mit einer Programmiersprache nicht umgehen kann, dann landet 
man im "Fegefeuer".
Es gibt genügend andere Stolperfallen für Anfänger. Dazu zählt die 
Verwendung von Zeiger.

Wer weiss,  was bei einem Unterprogramm Aufruf passiert,  z.B Sichern 
von Register und PC, sowie die Funktion des Stack bei der Anlage lokaler 
Variablen, der kann auch sicher mit Goto umgehen. Richtig, dass Goto nur 
eingesetzt werden, wenn andere Konstrukte scheitern oder das Programm 
unübersichtlich werden lassen.

von GEKU (Gast)


Lesenswert?

GEKU schrieb:
> andere Konstrukte scheitern oder das Programm unübersichtlich werden
> lassen

Z.B. wenn man aus einer Schleife aussteigen muss,  ohne den Code nach 
dem Schleifenkonstrukt zu exekutieren. Dann braucht man eine 
"Hilfsvariable" um diesen Code zu überspringen. Hier kann mit Hilfe von 
Goto aus der Schleife heraus der Code übersprungen werden, ohne diese 
Hilfsvaraible zu benötigen. Es reicht eine Marke nach dem zu 
überspringenden Code zu setzen.

von Maxim B. (max182)


Lesenswert?

GEKU schrieb:
> Z.B. wenn man aus einer Schleife aussteigen muss,  ohne den Code nach
> dem Schleifenkonstrukt zu exekutieren.

"break" reicht nicht?

von Yalu X. (yalu) (Moderator)


Lesenswert?

HGier mal ein kleines Beispiel,

Peter S. schrieb:
> um bei bestimmen Bedingungen (wenn eine if-Abfrage wahr ist) wieder
> zum Anfang des Programms zu kommen und alle folgenden Befehle zu
> ignorieren

unter Verwendung des bereits vorgeschlagenen setjmp/longjmp:

1
#include <stdio.h>
2
#include <setjmp.h>
3
4
static jmp_buf env;
5
static int error = 1;
6
7
void sub2(void) {
8
  printf("sub2\n");
9
  if(error)
10
    longjmp(env, 1);
11
  printf("nie erreicht in sub2\n");
12
}
13
14
void sub1(void) {
15
  printf("sub1\n");
16
  sub2();
17
  printf("nie erreicht in sub1\n");
18
}
19
20
int main(void) {
21
  while(setjmp(env))
22
    printf("Neustart\n");
23
24
  printf("main\n");
25
  sub1();
26
  printf("nie erreicht in main\n");
27
}

Ausgabe:

1
main
2
sub1
3
sub2
4
Neustart
5
main
6
sub1
7
sub2
8
Neustart
9
main
10
...

von Dumdi D. (dumdidum)


Lesenswert?

Maxim B. schrieb:
> GEKU schrieb:
>> Z.B. wenn man aus einer Schleife aussteigen muss,  ohne den Code nach
>> dem Schleifenkonstrukt zu exekutieren.
>
> "break" reicht nicht?

Gibt kein 'doppelbreak' for zwei oder mehr Schleifen.

von A. S. (Gast)


Lesenswert?

GEKU schrieb:
> Im Gegensatz zu goto wird beim Verlassen das Stack wieder in den
> ursprünglichen Zustand versetzt,

Und was passiert beim goto?

von Rolf M. (rmagnus)


Lesenswert?

NichtWichtig schrieb:
> Oliver S. schrieb:
>> Wie immer bei solchen Fragen heißt die Gegenfrage: Warum?
>>
>> Oliver
>
> Warum willst Du das wissen?

Weil die Frage erstmal nach keiner guten Idee klingt und weil sie zu 
allgemein formuliert ist. Um eine optimale Antwort zu geben, muss man 
also erstmal wissen, wofür das ganze denn gebraucht wird.
In der gefragten Allgemeinheit (von beliebiger Stelle im Programm an 
beliebige andere Stelle springen) wäre tatsächlich setjmp/longjmp am 
ehesten passend. Allerdings wird das tatsächlich nur äußerst selten 
gebraucht. Selbst langjährige C-Programmierer setzen das extrem selten 
bis gar nie ein.

> Beantworte doch einfach die Frage.

Welches Auto ist das beste für mich? Details zu Anforderungen und 
Wünschen verrate ich nicht. Bitte beantworte "einfach" diese Frage…

F. F. schrieb:
> Wenn es sich aber um Programmierung von Mikrocontrollern handelt, sollte
> man so was tunlichst vermeiden.

Warum sollte das auf einem µC anders sein als auf dem PC?

GEKU schrieb:
> Wer weiss,  was bei einem Unterprogramm Aufruf passiert,  z.B Sichern
> von Register und PC, sowie die Funktion des Stack bei der Anlage lokaler
> Variablen, der kann auch sicher mit Goto umgehen.

Was haben die beiden denn miteinander zu tun? Register, Stack u.s.w sind 
Compiler-interne Implementationsdetails. goto ist ein Sprachkonstrukt, 
der vollkommen unabhängig davon definiert ist.

> Richtig, dass Goto nur eingesetzt werden, wenn andere Konstrukte
> scheitern oder das Programm unübersichtlich werden lassen.

Ja. Da gibt es wenige Anwendungsfälle, aber es gibt sie.

Maxim B. schrieb:
> GEKU schrieb:
>> Z.B. wenn man aus einer Schleife aussteigen muss,  ohne den Code nach
>> dem Schleifenkonstrukt zu exekutieren.
>
> "break" reicht nicht?

break überspringt nur den Code in der Schleife, nicht den danach.

: Bearbeitet durch User
von GEKU (Gast)


Lesenswert?

A. S. schrieb:
> GEKU schrieb:
> Im Gegensatz zu goto wird beim Verlassen das Stack wieder in den
> ursprünglichen Zustand versetzt,
>
> Und was passiert beim goto?

Bei einem Sprung innerhalb der Funktion braucht mit den Stack nichts 
gemacht werden.

Bei einem Sprung außerhalb der Funktion muss das Stack bereinigt 
werden.
Das heisst,  die  zuvor am Stack gesicherten Register müssen wieder 
hergestellt, der gesicherte Programmcounter verworfen und der Stack 
Pointer auf den Wert vor dem Unterprogrammaufruf gesetzt werden. 
Letzteres verwirft auch die lokalen Variablen, die am Stack liegen.

Diese Manipulationen lassen sich nur mit dem Inlineassambler, bei 
gesperrten Interrupts, bewerkstelligen. Daher sollten Gotos, die 
Labels außerhalb der eigenen Funktion anspringen tunlichst vermieden 
werden. Ausnahme Restart der Software. Aber auch hier gibt es bessere 
Methoden.

von GEKU (Gast)


Lesenswert?

Rolf M. schrieb:
> break überspringt nur den Code in der Schleife, nicht den danach

so ist es.

Aber vielleicht passiert in der Schleife etwas (z.B. Fehler beim Öffen 
einer Datei), dass die Abarbeitung des Codes unmittelbar nach dem 
Verlassen der  Schleife falsch wäre (z.B. Lesen einer ungeöffneten 
Datei) .

von Oliver S. (oliverso)


Lesenswert?

NichtWichtig schrieb:
> Beantworte doch einfach die Frage.


Na dann:
1
printf("Programm beendet. Bitte neu starten\n");
2
exit(42);

Oliver

von MaWin (Gast)


Lesenswert?

Rolf M. schrieb:
>> Beantworte doch einfach die Frage.
>
> Welches Auto ist das beste für mich? Details zu Anforderungen und
> Wünschen verrate ich nicht. Bitte beantworte "einfach" diese Frage…

Diese Analogie ist viel zu dumm! Ein Sprung und ein Auto daher nicht zu 
vergleichen.

von Axel S. (a-za-z0-9)


Lesenswert?

GEKU schrieb:
> sollten Gotos, die
> Labels außerhalb der eigenen Funktion anspringen tunlichst vermieden
> werden. Ausnahme Restart der Software.

Noch nicht mal dann. Zumindest wenn du mit Restart meinst "Sprung an den 
Anfang von main()". Denn der Stack wird auch dabei nicht aufgeräumt 
respektive initialisiert. Das passiert außerhalb von main() [1]

Jedes Mal, wenn man aus einer Funktion mit goto an den Anfang von main() 
springt, bleibt ein bißchen was auf dem Stack liegen. Mindestens die 
Rücksprungadresse; meist mehr, z.B. lokale Variablen der Funktion. Nach 
ein paar Zyklen (auf einem PC mit viel RAM ein paar Tausend Zyklen) 
läuft der Stack über und alles ist karpott.


[1] genauer gesagt passiert das bevor main() von der C 
Laufzeitumgebung aufgerufen wird. Genauso wie die Initialisierung des 
Datensegments.

von GEKU (Gast)


Lesenswert?

Rolf M. schrieb:
> Was haben die beiden denn miteinander zu tun? Register, Stack u.s.w sind
> Compiler-interne Implementationsdetails. goto ist ein Sprachkonstrukt,
> der vollkommen unabhängig davon definiert ist.

"goto ist ein Sprachkonstrukt,  der vollkommen unabhängig davon 
definiert ist" genau das ist das Problem. Die Sprache C erlaubt viele 
gefährliche Konstrukte. Wen man Anfänger ist und nichts dazu lernen 
will, aus Fehlern lernt man bekanntlich, dann sollte man die 
"ausgetretenen Pfade" nicht verlassen oder eine halbwegs sichere 
Sprache, wie z.B. Java, verwenden.

Ich bin kein Fan der Assembler-Programmierung,  aber ein Programmierer 
in Hochsprache,  sollte wissen, was Compiler aus dieser machen, und was 
auf der betroffenen Maschine (wichtig für Embedded Entwickler) abläuft.

von Dr. Sommer (Gast)


Lesenswert?

NichtWichtig schrieb:
> Beantworte doch einfach die Frage.

Die lässt sich so direkt nicht beantworten. Der Programmzustand besteht 
nämlich nicht nur darin, in welcher Zeile (Instruktion) der 
Programmzähler gerade steht, sondern auch im Zustand der Variablen. Da 
kein "Verlauf" der Variablen aufgezeichnet wird, sind alte 
Variablenwerte verloren. Wenn man also an eine bestimmte "Stelle" im 
Programm springen möchte, was soll dann in den Variablen stehen? Die 
Dinge, die dort zuvor mal standen (jetzt aber weg sind)? Bestimmte fixe 
Werte? Wenn die angesprungene Stelle zurück kehrt (return), wo soll sie 
dann hingehen? Ohne diese Angaben kann man die Frage nicht beantworten. 
Vielleicht fällt beim Bestimmen dieser Angaben auch auf, dass ein 
solcher Sprung wenig praktikabel ist.

von Oliver S. (oliverso)


Lesenswert?

Yalu X. schrieb:
> HGier mal ein kleines Beispiel,
> ...
> unter Verwendung des bereits vorgeschlagenen setjmp/longjmp:

Hier mal mit einer kleinen Ergänzung:
1
#include <stdio.h>
2
#include <setjmp.h>
3
#include <stdlib.h>
4
5
static jmp_buf env;
6
static int error = 1;
7
static int startwert = 0;
8
9
void sub2(void) {
10
  printf("sub2\n");
11
  if(error)
12
    longjmp(env, 1);
13
  printf("nie erreicht in sub2\n");
14
}
15
16
void sub1(void) {
17
  printf("sub1\n");
18
  sub2();
19
  printf("nie erreicht in sub1\n");
20
}
21
22
int main(void) {
23
  while(setjmp(env))
24
    printf("Neustart, startwert = %d\n", startwert++);
25
  printf("main\n");
26
  sub1();
27
  printf("nie erreicht in main\n");
28
}

Ausgabe:

main
sub1
sub2
Neustart, startwert = 0
main
sub1
sub2
Neustart, startwert = 1
main
sub1
sub2
Neustart, startwert = 2
main
sub1
sub2
Neustart, startwert = 3
main
sub1
sub2
Neustart, startwert = 4
main
sub1
sub2
Neustart, startwert = 5
main
sub1
sub2
Neustart, startwert = 6
main
sub1
sub2
Neustart, startwert = 7
main
sub1
sub2
Neustart, startwert = 8
main
sub1
sub2
Neustart, startwert = 9

;)

Oliver

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

leo schrieb:
> setjmp/longjmp

Es gibt gute Gründe, warum erfahrene Programmierer diese nicht 
einsetzen.
Gerade bei komplexen Programmen möchte man nur definierte Abläufe und 
kein wildes Umhergespringe. Sonst sieht man später selber nicht mehr 
durch, d.h. der Code wird fehleranfällig und schwer erweiterbar.

Ich habe es mal ausprobiert und man kann beim AVR sogar aus Interrupts 
heraus springen, aber ich hatte bisher keine Notwendigkeit, es auch 
praktisch einzusetzen. D.h. es hätte nichts vereinfacht oder verbessert.

von GEKU (Gast)


Lesenswert?

Axel S. schrieb:
> Denn der Stack wird auch dabei nicht aufgeräumt respektive
> initialisiert.

Beim Sprung auf den Anfang von Main geht viel mehr schief. Selbst ein 
Sprung auf die Restart Adresse  (erster Code, der nach einem Power On 
ausgefühert) bereinigt nicht alles. Z.B. Werden Register von embedded 
Komponenten nicht zurückgesetzt und initialisiert. Daher ist es besser 
einen Wachdog auszulösen, der einen HW Reset durchführt.

Dann kann man nur hoffen, dass nicht nicht initaliserter  Speicher 
verwendet wird, um Zustände über einen harten Reset hinüber zu retten.

Windows verwendet sogar die Festplatte um dies zu tun.

von GEKU (Gast)


Lesenswert?

Dumdi D. schrieb:
> Maxim B. schrieb:
> GEKU schrieb:
> Z.B. wenn man aus einer Schleife aussteigen muss,  ohne den Code nach
> dem Schleifenkonstrukt zu exekutieren.
>
> "break" reicht nicht?
>
> Gibt kein 'doppelbreak' for zwei oder mehr Schleifen.

Höchsten einen Trick.

Man legt den verschachtelten Schleifenkonstrukt in ein eigenes 
Unterprogramm und verlässt die Schleife vorzeigen mit einem return.

So kann man auch aus verschachtelten Schleifen sicher aussteigen. Auch 
ein goto  wäre möglich, solange man die Programmebene nicht verlässt.

von GEKU (Gast)


Lesenswert?

GEKU schrieb:
> Auch ein goto  wäre möglich, solange man die Programmebene nicht
> verlässt.

Würde ich nicht machen, da man auch lokale Variable in einem Block {} 
generieren kann und diese von eine  GOTO bei einem Sprung aus dem Block 
vermutlich nicht bereinigt werden.

von Oliver S. (oliverso)


Lesenswert?

Was dann alles letztendlich wieder zu der Frage an den (wie erwartet 
nach der Fragestellung verschollenen) TO führt: Warum?

Oliver

von Dirk B. (dirkb2)


Lesenswert?

GEKU schrieb:
> Würde ich nicht machen, da man auch lokale Variable in einem Block {}
> generieren kann

Das ist nur eine Frage der Sichtbarkeit.
Denn in der Funktion darf sich der Stackpointer nicht ändern, sonst gibt 
es Probleme beim Variablenzugriff.

von Dirk K. (merciless)


Lesenswert?

http://xyproblem.info/ ???

merciless

von Dr. Sommer (Gast)


Lesenswert?

Karl schrieb:
> Genau, führt direkt in die Hölle!!!

https://xkcd.com/292/

von тролхантэр (Gast)


Lesenswert?

Der poster hat sich nicht mehr gemeldet, also weg mit dem Troll

von Bernd (Gast)


Lesenswert?

тролхантэр schrieb:

> Der poster hat sich nicht mehr gemeldet, ...

Hat die üblichen Verdächtigen nicht gehindert den Thread vollzumachen.

von Udo S. (urschmitt)


Lesenswert?

Bernd schrieb:
> Hat die üblichen Verdächtigen nicht gehindert den Thread vollzumachen.

Sommerloch.
Das dauert hier allerdings 12 Monate pro Jahr.

von Maxim B. (max182)


Lesenswert?

Rolf M. schrieb:
> break überspringt nur den Code in der Schleife, nicht den danach.

Man kann auch "return" benuzen. Dann ist man aus allen Schleifen dieser 
Funktion raus.

von F. F. (foldi)


Lesenswert?

Peter D. schrieb:
> Ich habe es mal ausprobiert und man kann beim AVR sogar aus Interrupts
> heraus springen, aber ich hatte bisher keine Notwendigkeit, es auch
> praktisch einzusetzen. D.h. es hätte nichts vereinfacht oder verbessert.

Bin immer sehr an deinen Beiträgen hinsichtlich C interessiert.
Und sehr interessant, dass das geht.
Aber wie kommt man auf so eine Idee?
Den Interrupt soll man doch sowieso so schnell wie möglich verlassen (so 
empfiehlt es zumindest die Literatur, die ich gelesen habe) und 
außerhalb der ISR weiter verarbeiten.

Gibt es eigentlich ein Quasistandard für die Programmierung von 
Mikrocontroller?
Also wie Programme aufgebaut sein sollten und Literatur darüber?

Beitrag #5910306 wurde von einem Moderator gelöscht.
von Mach (Gast)


Lesenswert?

Yalu X. schrieb:
> Hier mal ein kleines Beispiel,
> unter Verwendung des bereits vorgeschlagenen setjmp/longjmp:

Wird der Stack in diesem Fall bereinigt?
(Ich vermute mal nicht, da die Variable 'env' darauf hindeutet, dass die 
Zieladresse erst zur Laufzeit bestimmt wird, der Compiler eine 
notwendige Stackbereinigung also nicht einplanen kann.)

von Mach (Gast)


Lesenswert?

Mach schrieb:
> (Ich vermute mal nicht
Nachtrag: Ich vermute doch. Der Stackpointer kann ja bei setjmp einfach 
gesichert werden.

von Oliver S. (oliverso)


Lesenswert?

Mach schrieb:
> Ich vermute mal nicht,
Mach schrieb:
> Nachtrag: Ich vermute doch.

Vermuten, raten, schätzen, und glauben ist bei solchen Fragestellungen 
definitiv nicht zielführend.

RTFM

Oliver

von Peter D. (peda)


Lesenswert?

Oliver S. schrieb:
> Vermuten, raten, schätzen, und glauben ist bei solchen Fragestellungen
> definitiv nicht zielführend.

Es gibt doch so viele schöne Artikel, die alles ganz genau erklären.
Neu war für mich, daß nur einfache Vergleiche zulässig sind. Man darf 
also nicht setjmp() einer Variablen zuweisen.

von Peter D. (peda)


Lesenswert?

F. F. schrieb:
> Aber wie kommt man auf so eine Idee?

Z.B. Du hast eine Schleife, wo es auf ganz genaues Timing ankommt und 
die an vielen verschiedenen Stellen hängen bleiben kann. Dann kannst Du 
vorher einen Timerinterrupt aufsetzen, der sie abbrechen kann, ohne 
ständig die Abbruchbedingung testen zu müssen.

von Michael K. (Gast)


Lesenswert?

Peter S. schrieb:
> Gibt es einen Befehl

Goto habe ich bisher nur einmal gebraucht, weil ich zu faul war meinen 
eigentlichen Fehler zu korrigieren und statt dessen sauberen Code zu 
schreiben.

von Nachdenklicher (Gast)


Lesenswert?

Karl schrieb:
> Maxim B. schrieb:
>> Aber Verwendung von "Goto" ist nicht empfohlen.
>
> Genau, führt direkt in die Hölle!!

goto hell springt also direkt nach 0x666?

F. F. schrieb:
> ... und landet dann bei Wolfgang Petri.
> Hölle, Hölle, Hölle.

Das ist schlimmer als ein Schwarm Gotos. VIEL schlimmer.

von A. S. (Gast)


Lesenswert?

GEKU schrieb:
> Bei einem Sprung innerhalb der Funktion braucht mit den Stack nichts
> gemacht werden.
Ja
> Bei einem Sprung außerhalb der Funktion muss das Stack bereinigt
> werden.
seit wann geht das mit goto in C?

> ↑ ↓ 3.6.6.1 The goto statement
> Constraints
>
> The identifier in a goto statement shall name a label located somewhere in the 
current function.
>
> Semantics
>
> A goto statement causes an unconditional jump to the statement prefixed by the 
named label in the current function.

von DPA (Gast)


Lesenswert?

Nachdenklicher schrieb:
> goto hell springt also direkt nach 0x666?

Woher weisst du, das die Addresse der Hölle in Base16 ist? Oder muss man 
vor 666 in jeder Basis aufpassen? Also sind all die Zahlen höllisch?
1
666, interpretiert als basis y, geschrieben in basis x:
2
3
   7    8    9   10   11  12  13  14  15  16 base
4
                                              
5
 666  526  420  342  291 246 204 1a6 17c 156    7
6
1164  666  536  438  369 306 279 234 1e3 1b6    8
7
1410 1042  666  546  457 396 330 2b0 266 222    9
8
1641 1232  820  666  556 476 3c3 358 2e6 29a   10
9
2220 1436 1076  798  666 566 495 410 383 31e   11
10
2514 1656 1256  942  787 666 576 4b4 42c 3ae   12
11
3126 2112 1450 1098  909 776 666 586 4d3 44a   13
12
3456 2362 1656 1266  a51 896 765 666 596 4f2   14
13
4134 2646 1876 1446 10a5 a06 873 754 666 5a6   15
14
4530 3146 2220 1638 125a b46 990 850 743 666   16

von Nachdenklicher (Gast)


Lesenswert?

DPA schrieb:
> Also sind all die Zahlen höllisch?

Jap, hell is everywhere.

von Mach (Gast)


Lesenswert?

Oliver S. schrieb:
> Vermuten, raten, schätzen, und glauben ist bei solchen Fragestellungen
> definitiv nicht zielführend.
Halt dich doch dem Forum fern, wenn du kein Bock auf Kommunikation hast. 
Natuerlich koennte ichs nachschauen, die Frage (und Antwort darauf) ist 
aber vielleicht (vermutlich~) auch fuer andere interessant.
Zumal es da auch um Compiler-Internas geht, wie wird der Stack 
aufgeraeumt.
Und wenn das mittels longjmp geht, koennte der Compiler das auch fuer 
Goto erledigen. Also Spruenge ueber Funktionsgrenzen hinweg erlauben und 
trotzdem den Stack sauber halten.

von GEKU (Gast)


Angehängte Dateien:

Lesenswert?

F. F. schrieb:
> Also wie Programme aufgebaut sein sollten und Literatur darüber?

Dieses Buch kann ich nur empfehlen.

von Volle (Gast)


Lesenswert?

als gute Gründe für die Verwendung von Goto gibt es:

- in der Kantine alleine an einem Tisch ist schön ruhig
- Der Titel "schlechtester Programmierer es Monats" ist besser als kein 
Titel
- man kann den Kollegen der die Funktion verwenden wird nicht leider
- letzten Monat gab es kein Gehalt
- Kündigung ist schon abgeschickt
- ...

von Oliver S. (oliverso)


Lesenswert?

Mach schrieb:
> Zumal es da auch um Compiler-Internas geht, wie wird der Stack
> aufgeraeumt.
> Und wenn das mittels longjmp geht, koennte der Compiler das auch fuer
> Goto erledigen. Also Spruenge ueber Funktionsgrenzen hinweg erlauben und
> trotzdem den Stack sauber halten.

Da es hier aber nicht um irgend eine hypothetische Programmiersprache, 
sondern ganz konkret um C geht, kommt es nicht drauf an, was alles sein 
könnte, sondern nur, was die Sprachdefinition dazu sagt. Compilerintenas 
haben damit nur so viel zu tun, als daß die Compiler den Sprachstandard 
zu implemetieren haben.

goto in C springt ohne jede sonstige Aktionen zum Sprungziel, und das 
schon seit Anbeginn der C-Zeitrechnung.

Oliver

von GEKU (Gast)


Lesenswert?

Oliver S. schrieb:
> goto in C springt ohne jede sonstige Aktionen zum Sprungziel, und das
> schon seit Anbeginn der C-Zeitrechnung.

Genau so ist es. Ums Stack muss sich der Programmierer kümmern..

von F. F. (foldi)


Lesenswert?

GEKU schrieb:
> F. F. schrieb:
>> Also wie Programme aufgebaut sein sollten und Literatur darüber?
>
> Dieses Buch kann ich nur empfehlen.

Danke!

von Sven L. (svenl)


Lesenswert?

Goto als Vorwärtssprung innerhalb der gleichen Funktion ist durchaus 
legitim und habe ich auch häufiger gemacht, um wartbaren und lesbaren 
Code zu erhalten der mit allen anderen Konstrukten wie Kraut und Rüben 
aussah.

Zum Herausspringen aus mehreren verschachtelten Schleifen, ohne sich 
irgendwelche Abbruch-Variablen zu merken. Parserfunktionen sind solche 
Konstrukte, die bei einem Fehler möglichst schnell und zielgerichtet 
abbrechen sollen. Dort macht ein Vorwärtssprung aus der untersten 
Schleifenebene an das Ende der Funktion durchaus Sinn.

Goto ist per se kein schlechtes Konstrukt, es verleitet nur unerfahrene 
Programmierer es zu misbrauchen. Fakt ist aber auch, dass man auch ohne 
Goto Code schreiben kann, der genau die gleiche Funktionalität bietet. 
Ob der dann so sauber aussieht, steht auf einem anderen Blatt.

Viele Grüße!

Sven

von Michael K. (Gast)


Lesenswert?

Sven L. schrieb:
> Goto ist per se kein schlechtes Konstrukt, es verleitet nur unerfahrene
> Programmierer es zu misbrauchen.

Danke!
Teil der Sprachstandards, aber alle brechen in Tränen aus wenn man es 
verwendet.
Also ob man nicht auch ohne goto unleserlichen Bockmist schreiben 
könnte.

von Nop (Gast)


Lesenswert?

Peter S. schrieb:
> Zum Beispiel, um bei bestimmen
> Bedingungen (wenn eine if-Abfrage wahr ist) wieder zum Anfang des
> Programms zu kommen und alle folgenden Befehle zu ignorieren?

Was Du brauchst, ist vor allem mal eine vernünftige Programmstruktur 
anstalle Deines Kraut&Rüben-Verhaus, dann stellt sich diese Frage gar 
nicht erst.

von Stefan F. (Gast)


Lesenswert?

Michael K. schrieb:
> Teil der Sprachstandards, aber alle brechen in Tränen aus wenn man es
> verwendet.

Man muss ja nicht alle Sprachkonstrukte benutzen. Ich stehe z.B, immer 
noch mit Templates auf Kriegsfuß - egal, ich kann auch ohne sie 
programmieren.

Oder Lambda Ausdrücke - ein paar beeindruckende Beispiele habe ich 
gesehen. Die meisten Anwendungen lesen sich für mich jedoch wie 
Strickmuster.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Mach schrieb:
> Yalu X. schrieb:
>> Hier mal ein kleines Beispiel,
>> unter Verwendung des bereits vorgeschlagenen setjmp/longjmp:
>
> Wird der Stack in diesem Fall bereinigt?

Ja.

Peter D. schrieb:
> leo schrieb:
>> setjmp/longjmp
>
> Es gibt gute Gründe, warum erfahrene Programmierer diese nicht
> einsetzen.

Erfahrene Programmierer setzen setjmp/longjmp (wie auch goto) genau dort
ein, wo es sinnvoll ist :)

Peter D. schrieb:
> Neu war für mich, daß nur einfache Vergleiche zulässig sind. Man darf
> also nicht setjmp() einer Variablen zuweisen.

Das darf man schon. Es ist aber gängige Praxis, direkt nach dem Aufruf
von setjmp zu verzweigen, weswegen man sich eine zusätzliche Variable
sparen kann.

von Rolf M. (rmagnus)


Lesenswert?

MaWin schrieb:
> Diese Analogie ist viel zu dumm!

Merke: Nicht alles, was du nicht verstehst, ist dumm.

Maxim B. schrieb:
> Rolf M. schrieb:
>> break überspringt nur den Code in der Schleife, nicht den danach.
>
> Man kann auch "return" benuzen. Dann ist man aus allen Schleifen dieser
> Funktion raus.

Dann ist man aber gleich komplett aus der Funktion raus. Außerdem hatten 
wir letztens erst eine Diskussion dazu, ob es guter Stil ist, kreuz und 
quer in der Funktion returns zu verteilen. Spätestens wenn du noch vor 
dem Verlassen irgendwas aufräumen musst, wird's unschön.

Mach schrieb:
> Mach schrieb:
>> (Ich vermute mal nicht
> Nachtrag: Ich vermute doch. Der Stackpointer kann ja bei setjmp einfach
> gesichert werden.

Genau deshalb gibt's ja setjmp.

Volle schrieb:
> als gute Gründe für die Verwendung von Goto gibt es:

Schon witzig, wie manche geradezu dazu indoktriniert wurden, goto blind 
zu hassen, statt das Ganze nüchtern und technisch zu betrachten und es 
einfach da (und nur da) zu nutzen, wo es nützlich ist - so wie man das 
mit anderen Sprachkonstrukten auch tut.

von Christopher J. (christopher_j23)


Lesenswert?

GEKU schrieb:
> Oliver S. schrieb:
>> goto in C springt ohne jede sonstige Aktionen zum Sprungziel, und das
>> schon seit Anbeginn der C-Zeitrechnung.
>
> Genau so ist es. Ums Stack muss sich der Programmierer kümmern..

Nein, um den kümmert sich der Compiler. Mit goto kann man die Funktion 
nicht verlassen, siehe

A. S. schrieb:
>> ↑ ↓ 3.6.6.1 The goto statement
>> Constraints
>> The identifier in a goto statement shall name a label located somewhere
>> in the current function.
>> Semantics
>> A goto statement causes an unconditional jump to the statement prefixed
>> by the named label in the current function.

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

hier wird ja viel phantasiert und im kreis gedreht ...
und unsinn zu setjmp/longjmp verbreitet.

setjmp/longjmp in c ist NICHT ein "goto" zu zielen ausserhalb einer 
aktiven funktion sondern ein GO BACK zu einem beliebigen sprungziel das 
vorher schon mal besucht wurde und mit setjmp markiert wurde!
setjmp speichert also den zustand  zum zeitpunkt des besuches/aufrufes 
und dieser wird später rekonstruiert, wenn dorthin zurückgesprungen 
wird.

UND goto ist ein nützlices kontrukt um z.b. eine eihheitliche 
fehlerbehandlung zu realisieren, auch in parsern wird goto oft verwendet 
oder zur laufzeitoptimiereung in echtzeitkritschen bereichen.


mt

von Einer K. (Gast)


Lesenswert?

Rolf M. schrieb:
> wie manche geradezu dazu indoktriniert wurden, goto blind
> zu hassen,

Das machen die selber.
Selbstsuggestion.

Könnten ja auch nachdenken...
Ist aber zu unbequem, dann müsste man ja evtl. Einsicht zeigen.
Nee...
Die dogmatische Sicht, macht das Leben einfacher.
Da gibts wenigstens ein klares Gut und Böse.

------------

Goto hat seinen Ruf erlangt, als z.B. Basic noch keine Subroutinen 
und/oder benannte Lables kannte.

Diese wirklich schlimme Zeit/Erfahrung auf C/C++ zu projizieren, ist 
keine intellektuelle Glanzleistung.
In den C artigen Sprachen gab es nie die Notwendigkeit für einen 
extensiven Goto Gebrauch.

von Heiko L. (zer0)


Lesenswert?

Weil sich alles, was man mit goto machen konnte, auch mit anderen 
Konstrukten machen lässt.
1
switch(N) {
2
case 1:
3
  if(something) {
4
    case 2: return 0;
5
  }
6
default:
7
  return 1;
8
}

: Bearbeitet durch User
von max (Gast)


Lesenswert?

NichtWichtig schrieb:
> Oliver S. schrieb:
> Wie immer bei solchen Fragen heißt die Gegenfrage: Warum?
> Oliver
>
> Warum willst Du das wissen?
>
> Beantworte doch einfach die Frage.

Das ist hier Gang und Gebe.
Man kann hier keine simple Frage mehr stellen, ohne dass man gleich das 
ganze Projekt oder Vorhaben im Detail erlautert

von Oliver S. (oliverso)


Lesenswert?

max schrieb:
> an kann hier keine simple Frage mehr stellen, ohne dass man gleich das
> ganze Projekt oder Vorhaben im Detail erlautert

Doch. Kann man.
Aber die Frage ist nicht simple, und sehr vermutlich auch nicht 
sinnvoll, schon gar nicht bei dem offensichtlichen Anfängerstatus des 
TO.

Und daher: Was genau an

http://xyproblem.info/

hast du nicht verstanden?

Oliver

von Rolf M. (rmagnus)


Lesenswert?

Heiko L. schrieb:
> Weil sich alles, was man mit goto machen konnte, auch mit anderen
> Konstrukten machen lässt.

Es gibt vieles, das man durch andere Konstrukte ersetzen kann. Das heißt 
noch lange nicht, dass der Code dadurch gezwungenermaßen besser wird.

Beitrag #5911983 wurde von einem Moderator gelöscht.
von S. R. (svenska)


Lesenswert?

GEKU schrieb:
>> Auch ein goto  wäre möglich, solange man
>> die Programmebene nicht verlässt.
>
> Würde ich nicht machen, da man auch lokale Variable
> in einem Block {} generieren kann und diese von eine
> GOTO bei einem Sprung aus dem Block vermutlich nicht
> bereinigt werden.

Du vermutest falsch. Lerne bitte C.

GEKU schrieb:
>> goto in C springt ohne jede sonstige Aktionen zum Sprungziel,
>> und das schon seit Anbeginn der C-Zeitrechnung.
>
> Genau so ist es. Ums Stack muss sich der Programmierer kümmern..

Das ist falsch[*]. Man kann nicht mit "goto" aus einer Funktion 
herausspringen[*]. Lerne bitte C.

[*] Ausnahme: computed goto, aber das ist eine GCC-Erweiterung.

von Feststeller (Gast)


Lesenswert?

S. R. schrieb:

> Du vermutest falsch. Lerne bitte C.

Warum bittest Du ihn, das zu tun? Warum sollte sich jemand sein 
Vermögen, logisch denken zu können mit so einem Rotz kaputt machen?

von F. F. (foldi)


Lesenswert?

Bei der ganzen Diskussion um "goto" habe ich mir überlegt, ob es einen 
Grund geben könnte ganz aus dem Programmablauf auf einem Mikrocontroller 
aus zu steigen, sodass er wirklich nichts mehr macht.
Hat schon einmal jemand so was gemacht und gäbe es relevante Gründe 
(Sicherheitsabbruch) das zu tun?

von Einer K. (Gast)


Lesenswert?

Ja!

Dafür wurde exit() erfunden.

von Stefan F. (Gast)


Lesenswert?

F. F. schrieb:
> ob es einen
> Grund geben könnte ganz aus dem Programmablauf auf einem Mikrocontroller
> aus zu steigen, sodass er wirklich nichts mehr macht.

Wo willst du denn hin springen, ins Nirvana?

Wenn der Mikrocontroller nichts mehr machen soll, musst du alle I/O 
Funktionen stoppen (Timer, DMA, etc.) und dann in eine Endlosschleife 
gehen.

Genau so macht es auch dein Windows, wenn du es auf einem Rechner 
herunter fährst, der sich nicht selbst aus schalten kann.

von F. F. (foldi)


Lesenswert?

Ja klar, so würde ich es machen.
Mir kam da halt der Gedanke an einen Notfallausstieg.
Aber auch da gibt es andere Wege.

von Peter D. (peda)


Lesenswert?

F. F. schrieb:
> Bei der ganzen Diskussion um "goto" habe ich mir überlegt, ob es einen
> Grund geben könnte ganz aus dem Programmablauf auf einem Mikrocontroller
> aus zu steigen, sodass er wirklich nichts mehr macht.

In der Tuningszene gibt es Geräte um das Motorsteuergerät zu tunen. 
Damit nun nicht jemand sein Gerät nach getaner Arbeit weiter verkauft, 
führt dieses als letztes Kommando ein Full-Erase durch. Danach rennt die 
CPU nur noch durch den gelöschten Flash und führt 0xFF aus.

von W.S. (Gast)


Lesenswert?

Stefanus F. schrieb:
> Wenn der Mikrocontroller nichts mehr machen soll, musst du alle I/O
> Funktionen stoppen (Timer, DMA, etc.) und dann in eine Endlosschleife
> gehen.

Das ist aber fast regelmäßig das Gegenteil dessen, was man von einem µC 
haben will. Der soll sich nicht sang- und klanglos aufhängen, sondern 
wenigstens einen Restart durchführen.

Ob da der Watchdog als Brutalknüppel die richtige Wahl ist, halte ich 
für diskussionswürdig.

Dezenter geht's auch, indem man im Startupcode einen Einsprung für einen 
Warmstart vorsieht und beim Setup des ganzen µC eben auch den Fall 
bedenkt, daß der Setup eben nicht immer darauf bauen darf, daß alle 
Hardware im Defaultzustand nach Reset vorliegt.

W.S.

von Bernd K. (prof7bit)


Lesenswert?

Stefanus F. schrieb:
> F. F. schrieb:
>> ob es einen
>> Grund geben könnte ganz aus dem Programmablauf auf einem Mikrocontroller
>> aus zu steigen, sodass er wirklich nichts mehr macht.
>
> Wo willst du denn hin springen, ins Nirvana?

In die wirkliche Welt natürlich. Wie am Ende von 13th Floor.

: Bearbeitet durch User
von Junger Hüpfer (Gast)


Lesenswert?

GEKU schrieb:
> Axel S. schrieb:
>> Denn der Stack wird auch dabei nicht aufgeräumt respektive
>> initialisiert.
>
> Beim Sprung auf den Anfang von Main geht viel mehr schief.

Das kann ich bestätigen. Gesprungen, unglücklich aufgekommen, noch 
versucht, am Stackpointer festzuhalten -> Der ist umgefallen, alle 
Rücksprungadressen lagen kreuz und quer -> ausgerutscht und Sprunggelenk 
gebrochen.

von GEKU (Gast)


Lesenswert?

F. F. schrieb:
> Also wie Programme aufgebaut sein sollten und Literatur darüber?



Programmierstil, Fallstricke, Module

http://www.netzmafia.de/skripten/programmieren/ad13.html#10.1

Zu Empfehlen, kostet nichts!

von F. F. (foldi)


Lesenswert?

GEKU schrieb:
> Zu Empfehlen

Jau!
Danke!

von Rolf M. (rmagnus)


Lesenswert?

Feststeller schrieb:
> S. R. schrieb:
>
>> Du vermutest falsch. Lerne bitte C.
>
> Warum bittest Du ihn, das zu tun?

Weil es keinen Sinn hat, in so einer Diskussion mit Vermutungen und 
Spekulationen um sich zu werfen.

F. F. schrieb:
> Bei der ganzen Diskussion um "goto" habe ich mir überlegt, ob es einen
> Grund geben könnte ganz aus dem Programmablauf auf einem Mikrocontroller
> aus zu steigen, sodass er wirklich nichts mehr macht.
> Hat schon einmal jemand so was gemacht und gäbe es relevante Gründe
> (Sicherheitsabbruch) das zu tun?

Kann z.B. vorkommen, wenn ein schwerwiegender Fehler aufgetreten ist. 
Dann springt man in eine Routine, die hoffentlich noch irgendeine 
Meldung rausbekommt und dann in eine Endlosschleife geht, bis der 
Watchdog dann automatisch den ganzen Prozessor neu startet.

Arduino Fanboy D. schrieb:
> Ja!
>
> Dafür wurde exit() erfunden.

Um µCs ins Nirvana zu schicken? Eher nicht.

: Bearbeitet durch User
von A. S. (Gast)


Lesenswert?

Rolf M. schrieb:
>> Dafür wurde exit() erfunden.
>
> Um µCs ins Nirvana zu schicken? Eher nicht.

Naja, exit() ist beim µC, was Du draus machst.

Es ist halt Konvention, auch wenn Du FatalError() oder sonstwas 
festlegen kannst.

von Einer K. (Gast)


Lesenswert?

A. S. schrieb:
> Naja,

Eigentlich hatte ich gedacht: "Lass ihn!"
Hat er doch eine so schöne Gelegenheit gefunden mir einen 
einzuschenken...

https://www.microchip.com/webdoc/AVRLibcReferenceManual/group__avr__stdlib_1ga137096a48cc0c731052cadfb69c39b34.html
Ich finde, das ist doch schon eine Form von Nirvana.
evtl. vielleicht gibts unterschiedliche Vorstellungen davon, was "µC im 
Nirvana" bedeutet.

Wenn man mehr erreichen möchte, z.B. PWMs abschalten, sollte man das vor 
dem exit() tun(C), oder es den Destruktoren überlassen(C++).

Ok, ok, das gilt jetzt erstmal nur für AVRs.
Aber immerhin sind das µC !

von Rolf M. (rmagnus)


Lesenswert?

Arduino Fanboy D. schrieb:
> Aber immerhin sind das µC !

Ich hab nicht behauptet, dass man es auf µCs nicht einsetzen kann, 
sondern lediglich der Behauptung widersprochen, dass es dafür gemacht 
sei.

von Einer K. (Gast)


Lesenswert?

F. F. schrieb:
> habe ich mir überlegt, ob es einen
> Grund geben könnte ganz aus dem Programmablauf auf einem Mikrocontroller
> aus zu steigen, sodass er wirklich nichts mehr macht.

Arduino Fanboy D. schrieb:
> Ja!
>
> Dafür wurde exit() erfunden.

Rolf M. schrieb:
> sondern lediglich der Behauptung widersprochen, dass es dafür gemacht
> sei.

exit() wurde erfunden, um aus einem laufendem Programm aus zu steigen.
Oder, was sind die Wurzeln/Zweck des exit()?


Dass es auf einem µC etwas anders wirkt, als unter einem OS getriebenem 
System, sollte einen jetzt nicht so dolle verwundern, denke ich mal.

In Verbindung mit dem/einem WDT ist das eine recht zuverlässige Nummer, 
auch für den TO.

von Michael K. (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> In Verbindung mit dem/einem WDT ist das eine recht zuverlässige Nummer,
> auch für den TO.

D.H. ich schicke die MCU nach Irgendwo und vertraue darauf das der 
Compiler das schon zu irgendwas sinnvollem komplettieren wird.

Grelle Idee aber warum?
Wenn der anhalten soll, dann halte ich den an.
Wenn der resetten soll, dann löse ich einen Software Reset aus.

Und warum sollte der TO einen WDT zielführend einsetzen können, wenn das 
schon geschätzen 50% der eher nebenbei Programmierenden erheblich zu 
hoch ist?

von Einer K. (Gast)


Lesenswert?

Michael K. schrieb:
> Wenn der resetten soll, dann löse ich einen Software Reset aus.
Wie willst du das tun, wenn der betreffende µC keine Möglichkeit kennt?
z.B. die AVR

Michael K. schrieb:
> D.H. ich schicke die MCU nach Irgendwo und vertraue darauf das der
> Compiler das schon zu irgendwas sinnvollem komplettieren wird.
Natürlich!
Ist es doch genau das, was "Programmierer" tagtäglich tun.
Vertrauen, dass der Kompiler genau das tut, was man sich von ihm 
wünscht.

Was exit() tut, ist in der AVR LibC definiert!
Oder stellst du alles in Frage, was diese Lib bietet?

Wie der WDT agiert, ist im Datenblatt des µC beschrieben.
Glaubst du dem auch nicht?


Wenn du min. eine der Fragen mit JA beantwortest, dann wäre vielleicht 
auch dieses was für dich:
https://youtu.be/AXu5zRoUShw

von Michael K. (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Was exit() tut, ist in der AVR LibC definiert!

Toll wenn man nur diese eine MCU kennt.

Arduino Fanboy D. schrieb:
> Wenn du min. eine der Fragen mit JA beantwortest, dann wäre vielleicht
> auch dieses was für dich:
> Youtube-Video "Die Globus-Religion
Okay, Du bist ein Idiot.
Sorry, habe ich nicht gewusst.

von Einer K. (Gast)


Lesenswert?

Michael K. schrieb:
> Toll wenn man nur diese eine MCU kennt.

Dass sich diese (exit() und WDT) Aussage ausschließlich um AVR drehte, 
ist dir nicht aufgefallen?
Scheinbar nein.
Oder ist es dir nur egal?

Michael K. schrieb:
> Okay, Du bist ein Idiot.
Vielleicht solltest mal in einen Spiegel schauen, und diese Einschätzung 
drei mal laut wiederholen.

---
Oder anders?
Warum bist du an einer solchen Auseinandersetzung so interessiert?

von Oliver S. (oliverso)


Lesenswert?

Michael K. schrieb:
> Toll wenn man nur diese eine MCU kennt.

Die MCU ist doch völlig egal. Wenn es eine lib gibt, die eine Funktion 
exit enthält, sollte auch dokumentiert sein, was die macht. Ob man die 
dann sinnvoll verwenden kann, bleibt dem geneigten Programmierer 
überlassen.

Oliver

von Rolf M. (rmagnus)


Lesenswert?

Oliver S. schrieb:
> Michael K. schrieb:
>> Toll wenn man nur diese eine MCU kennt.
>
> Die MCU ist doch völlig egal. Wenn es eine lib gibt, die eine Funktion
> exit enthält, sollte auch dokumentiert sein, was die macht.

Wenn ich in eine Endlosschleife rennen will, kann ich auch einfach eine 
Endlosschleife hinschreiben, statt erst in der Doku nachzuschauen, ob 
bei der verwendeten libc exit() das zufällig auch tut.

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

GEKU schrieb:
> GEKU schrieb:
>> Auch ein goto  wäre möglich, solange man die Programmebene nicht
>> verlässt.
>
> Würde ich nicht machen, da man auch lokale Variable in einem Block {}
> generieren kann und diese von eine  GOTO bei einem Sprung aus dem Block
> vermutlich nicht bereinigt werden.

Mit der Betonung auf "vermutlich".

Hier ein Beispiel, wie eine Bereinigung stattfindet:
1
void f (char*);
2
3
char func (char a, unsigned char b)
4
{
5
    if (a < 'P')
6
    {
7
        char c[b];
8
        f (c);
9
        if (a < 'M')
10
            goto end;
11
        f (c);
12
    }
13
    a++;
14
end:
15
    return a;
16
}

Abhängig von a wird Array c[] initialisiert, dessen Größe erst zur 
Laufzeit bekannt ist. f() dient nur der Verwendung von c[].  Je nach a 
wird der Block vorzeitig verlassen und ans Ende der Funktion gesprungen, 
und c[] wird danach im Block noch 1x verwendet, kann also nicht vor dem 
goto aufgeräumt werden.

Code (avr-gcc):

c[] wird in Zeile :12 auf den Stack angelegt, der Wert von SP wird in 
R14/15 gemerkt (Zeilennummern siehe asm-Kommentar).

Nach dem goto-Vergleich in :14 wird in beiden Pfaden SP wieder aus 
R14/15 hergestellt.
1
func:
2
  push r12
3
  push r13
4
  push r14
5
  push r15
6
  push r17
7
/* prologue: function */
8
  mov r17,r24   ;  a, a
9
 ;  foo.c:21: }
10
  in r14,__SP_L__   ;  tmp55
11
  in r15,__SP_H__   ;  tmp55
12
 ;  foo.c:10:     if (a < 'P')
13
  cpi r24,lo8(80)   ;  a,
14
  brge .L2
15
 ;  foo.c:12:         char c[b];
16
  in r24,__SP_L__
17
  in r25,__SP_H__
18
  sub r24,r22   ; , b
19
  sbc r25,__zero_reg__
20
  out __SP_L__,r24
21
  out __SP_H__,r25
22
  adiw r24,1
23
  movw r12,r24   ;  tmp52,
24
 ;  foo.c:13:         f (c);
25
  call f
26
 ;  foo.c:14:         if (a < 'M')
27
  cpi r17,lo8(77)   ;  a,
28
  brge .L3
29
  out __SP_L__,r14   ;  tmp55
30
  out __SP_H__,r15   ;  tmp55
31
.L4:
32
 ;  foo.c:21: }
33
  mov r24,r17   ; , a
34
/* epilogue start */
35
  pop r17
36
  pop r15
37
  pop r14
38
  pop r13
39
  pop r12
40
  ret  
41
.L3:
42
 ;  foo.c:16:         f (c);
43
  movw r24,r12   ; , tmp52
44
  call f
45
  out __SP_L__,r14   ;  tmp55
46
  out __SP_H__,r15   ;  tmp55
47
.L2:
48
 ;  foo.c:18:     a++;
49
  subi r17,lo8(-(1))   ;  a,
50
  rjmp .L4

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.