error: jump to case label [gelöst]

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: error: jump to case label [gelöst]

Beitrag von Meillo » 03.09.2021 15:51:54

dakuan hat geschrieben: ↑ zum Beitrag ↑
03.09.2021 15:22:25
Ich denke, der Compiler macht sich das sehr einfach, indem er erstmal alles, was innerhalb des switch() Blocks als ein Scope sieht.
Das ist nunmal das Design von Switch in C/C++ ... Das ist halt sehr assemblerartig und nicht so modern wie das if in der gleichen Sprache. Und ja, das Design ist bestimmt auch so, weil das den Compiler einfacher gemacht hat ... also Anfang der 70er Jahre wo C entstanden ist ... und die Designidee ist sicher noch aelter, man hat sie an der Stelle einfach uebernommen, waehrend man bei den Schleifen z.B. modernere Designs gewaehlt hat, als damals ueblich.
Meillo schrieb:
Dass der Programmflow etwas ungewoehnlich ist, mag ja sein, aber warum informiert er nicht nur darueber, sondern bricht ab?
Den ungewöhnlichen Programmflow kann ich erklären. Das ist ein Event-Handler einer abgeleiteten Klasse. Der Rückgabewert 1 bedeutet "das Event wurde bearbeitet", da kann ich also direkt raus.

Es kann aber sein, dass die Klasse, von der ich abgeleitet habe, die Events haben will, die hier nicht beachtet wurden. Da müsste ich dann noch eine Ergebnisvariable mitführen und am Ende nochmal abfragen um dann zu entscheiden, ob der ursprüngliche Event-Handler noch informiert werden muss.
Ich habe eigentlich die Umsetzung eines Switch im vom Compiler erzeugten Code gemeint, was halt eine Goto-Springerei ist, ohne Scope und so.

An den Programmflow, wie du ihn verstanden hast, habe ich gar nicht gedacht ... und damit auch nicht an die Konsequenzen seiner Asynchronitaet. Jedoch sollte das nicht relevant sein, da die Definition und alle Verwendungen von `p' nur an einer Stelle sind und dazwischen nichts sonstiges passiert.



Es ist ja schon so, dass dieses ganze Switch-Zeug in C/C++ so seine Tuecken hat. Beispielsweise diese Sache:

Code: Alles auswählen

:-Q cat a.c
#include <stdio.h>

int
main(void)
{
        char c = 'x';

        switch (c) {
        case 'x':
                int i = 1;
                printf("i:%d\n", i);
        }
        return 0;
}


:-Q make a 
cc     a.c   -o a
a.c: In function ‘main’:
a.c:10:3: error: a label can only be part of a statement and a declaration is not a statement
make: *** [a] Error 1

:-Q 
... das kann ich aber nachvollziehen und verstehe die Gruende, waehrend das bei der Problem in diesem Thread nicht so ist.

Vielleicht sollten wir mal ein Minimalbeispiel erstellen, um der Sache naeher zu kommen ...
Use ed once in a while!

eggy
Beiträge: 3331
Registriert: 10.05.2008 11:23:50

Re: error: jump to case label

Beitrag von eggy » 03.09.2021 15:59:28

Meillo hat geschrieben: ↑ zum Beitrag ↑
03.09.2021 14:47:44
Die ganze Zeit habe ich das Gefuehl, dass ich irgendwas offensichtliches uebersehe ... :roll:
Die Grammatik. Nimm die oben verlinkte C Grammatik, die liest sich leichter.
Falls jemanden "BNF" nichts sagt,
https://de.wikipedia.org/wiki/Backus-Naur-Form
https://de.wikipedia.org/wiki/Erweitert ... -Naur-Form
kurz: das ist eine Art, mit der man beschreiben kann, wie eine Sprache aufgebaut ist. Es wird so das Regelwerk festgelegt, mit dem die Compiler arbeiten. Und es gilt: was da nicht drinsteht, "gibt's nicht" (aka undefined behavior, dann macht das Ding eben was es will - bzw. was Compilerbauer oder Mondphase sagen). Oftmals gibts dazu auch eine Darstellung als (Teil-)Graph.

Wenn man in die Zeile

Code: Alles auswählen

<labeled-statement> ::= <identifier> : <statement>
                      | case <constant-expression> : <statement>
                      | default : <statement>
schaut, sieht man: ein "label-statement" besteht entweder aus "identifier : statement" oder "case contant-expression : statement" oder "default : statement".
Also schaut man sich als nächstes "constant-expression" und "statement" an.
Und wenn man die alle solange verfolgt hat, bis man merkt nur noch im Kreis zu laufen, dann hat man rausgefunden: "declaration" kann in dem Teil des Graphen nur noch über "compound-statement" erreicht werden, und da sind halt die "{" "}" drum rum.

eggy
Beiträge: 3331
Registriert: 10.05.2008 11:23:50

Re: error: jump to case label [gelöst]

Beitrag von eggy » 03.09.2021 16:14:42

@Meillo: falls Dich die Thematik interessiert, schau dass Du ne alte Ausgabe vom "Drachenbuch" (Compilerbau von Aho - ja, der awk-Aho) bekommst. Die ganz alten Bände hatten ihre Beispiele noch in C Code, die neueren Versionen dann mit Java. Neuer ist wohl leichter/verständlicher(?) zu lesen, das alte für C Freunde vermutlich ergiebiger.


Makefile:

Code: Alles auswählen

OPTIONS= -O0 -S

all:
        @echo  "--------------------------------"
        @echo  " "
        - clang $(OPTIONS) clang_test_c.c  
        @echo  " "
        @echo  "--------------------------------"
        @echo  " "
        - clang++ $(OPTIONS)  clang_test_cpp.cpp  
        @echo  " "
        @echo  "--------------------------------"
        @echo  " "
        - gcc  $(OPTIONS) gcc_test_c.c  
        @echo  " "
        @echo  "--------------------------------"
        @echo  " "
        - g++  $(OPTIONS) gcc_test_cpp.cpp
        @echo  " "
        @echo  "--------------------------------"
        @echo  " "
test.irgendwas

Code: Alles auswählen

int main() {
                int value = 1;
                switch (value) {  
                                case 1: 
                                                int i = 23;
                                                break;

                                case 2: 
                                                return 2;
                }
}

Code: Alles auswählen

ln test.irgendwas clang_test_c.c
ln test.irgendwas clang_test_cpp.cpp
ln test.irgendwas gcc_test_c.c
ln test.irgendwas gcc_test_cpp.cpp
Oder hat jemand ne bessere Idee?

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: error: jump to case label

Beitrag von Meillo » 03.09.2021 17:17:18

eggy hat geschrieben: ↑ zum Beitrag ↑
03.09.2021 15:59:28
Meillo hat geschrieben: ↑ zum Beitrag ↑
03.09.2021 14:47:44
Die ganze Zeit habe ich das Gefuehl, dass ich irgendwas offensichtliches uebersehe ... :roll:
Die Grammatik. [...] dann hat man rausgefunden: "declaration" kann in dem Teil des Graphen nur noch über "compound-statement" erreicht werden, und da sind halt die "{" "}" drum rum.
Das ist schon klar. Warum nach einem Label keine Deklaration kommen kann, das wusste ich schon und habe damals dazu die Grammatik auch gelesen. (Das Dragon Book habe ich auch in meinem Buecherregel. Irgendwann habe ich auch mal den Anfang gelesen, aber weil ich nur gelesen und nicht parallel die Dinge auch ausprobiert habe, hat es dann irgendwann keinen Sinn mehr gemacht weiterzulesen, weil's ohne die Praxis zu abstrakt geworden ist.)

Wie dem auch sei. Mit meinem ``ich glaube, ich uebersehe etwas'' meine ich den Code von dakuan. Ich hatte nicht verstanden, welchen Grund der Compiler hat, diesen Fehler zu werfen.


Nach eigenem Testen und Recherchieren kann ich die Antwort nun aber geben. Der erleuchtende Satz war dieser (irgendwo aus dem GCC Bugtracker):``-fpermissive is a band-aid to work around broken code''. Der g++ verhindert hier, dass Code, der als unschoen und potenziell problematisch angesehen wird, durchgeht. Stattdessen sagt er einfach: Sowas macht man nicht! Aetsch!

Es gibt keinen sprachlichen Grund dafuer (was eben meine Frage war), sondern das ist nur dem erzieherischen Element der Compilerentwickler geschuldet, das zunehmend um sich greift, wie mir scheint. (Ob das gut oder schlecht ist, ist ein separates Thema.)


Hier ein Testprogramm, das zwar C-Code enthaelt aber mit g++ uebersetzt wird:

Code: Alles auswählen

:-Q cat b.c
#include <stdio.h>

int
main(void)
{
        printf("1\n");
        goto there;
        printf("2\n");
        int i = 0;
        printf("i:%d\n", i);
        printf("3\n");
there:
        printf("4\n");

        return 0;
}

:-Q CC=g++ make b
g++     b.c   -o b
b.c: In function ‘int main()’:
b.c:12:1: error: jump to label ‘there’ [-fpermissive]
b.c:7:7: error:   from here [-fpermissive]
b.c:9:6: error:   crosses initialization of ‘int i’
make: *** [b] Error 1

:-Q 
Mit `switch' hat die ganze Sache nur soviel zu tun, dass `switch' intern als Gotos zu den Case-Labels realisiert wird.



Btw @eggy: 16-Zeichen breite Tabs? 8O ... Ist das der neue Ansatz um sich tief verschachtelten Code abzugewoehnen? :mrgreen:
Use ed once in a while!

eggy
Beiträge: 3331
Registriert: 10.05.2008 11:23:50

Re: error: jump to case label [gelöst]

Beitrag von eggy » 03.09.2021 17:43:46

Meillo hat geschrieben: ↑ zum Beitrag ↑
03.09.2021 17:17:18
Btw @eggy: 16-Zeichen breite Tabs? 8O ... Ist das der neue Ansatz um sich tief verschachtelten Code abzugewoehnen? :mrgreen:
ähm ja ähm ... ka was da nun wieder passiert ist ... liegt wohl am Thema :roll: :mrgreen:

JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: error: jump to case label

Beitrag von JTH » 04.09.2021 12:13:40

Ich will auch nochmal :D Hatte gestern Mittag schon angefangen, hier was dazu zu schreiben, aber ihr wart bis zum Abend viel zu fleißig und habt das meiste vorweggenommen ;)

Meillo hat geschrieben: ↑ zum Beitrag ↑
03.09.2021 17:17:18
Wie dem auch sei. Mit meinem ``ich glaube, ich uebersehe etwas'' meine ich den Code von dakuan. Ich hatte nicht verstanden, welchen Grund der Compiler hat, diesen Fehler zu werfen.
[…]
Es gibt keinen sprachlichen Grund dafuer (was eben meine Frage war), […]
Doch, den gibt es tatsächlich. Es ist in C++, aber nicht in C, einfach ausdrücklich verboten, in den Gültigkeitsbereich einer Variablen über deren Deklaration hinweg hineinzuspringen:
https://en.cppreference.com/w/cpp/language/switch#Explanation hat geschrieben: Because transfer of control is not permitted to enter the scope of a variable, if a declaration statement is encountered inside the statement, it has to be scoped in its own compound statement:
Verbirgt sich im ISO-Standard anscheinend im Abschnitt zu Statements / Declaration statement. Da finde ich es aber nicht so leicht verständlich. Ein Hoch auf die Dokumentationen auf cppreference.com, die sind immer sehr hilfreich!

Meillo hat geschrieben: ↑ zum Beitrag ↑
03.09.2021 17:17:18
[…] sondern das ist nur dem erzieherischen Element der Compilerentwickler geschuldet, das zunehmend um sich greift, wie mir scheint.
Ich finds mit Blick auf die Fehler durch uninitialisierte Variablen, die es mit C und C++ ja oft gibt, nicht verkehrt, dass so eine Problemquelle hier ausdrücklich nicht nur durch die Compilerentwickler, sondern sogar durch den Sprachstandard ausgeschlossen ist.

Eine – logische – Folge der Regel: Der Compilefehler kommt nur, wenn man mehr als einen Case hat. Denn mit nur einem Case gibt es letztendlich keinen Sprung. Folgendes kompiliert als C++:
https://godbolt.org/z/WeTGY8jh7 hat geschrieben:

Code: Alles auswählen

int foo(int x)
{
    switch (x) {
        case 0:
            int a = 42;
            return a;
    }

    return 0;
}
Mit einem zusätzlichen Case scheitert es dann wieder wie bekannt.

Meillo hat geschrieben: ↑ zum Beitrag ↑
03.09.2021 17:17:18
Hier ein Testprogramm, das zwar C-Code enthaelt aber mit g++ uebersetzt wird:
Wenn du den Code mit dem g++ kompilierst, ist es in dem Moment doch C++-Code und wird mit entsprechenden Regeln wie der obigen übersetzt. Gültig ist er ja in beiden Sprachen.

Als C-Code würde dein (noch weiter) vereinfachtest Beispiel mit Überspringen der Variableninitialisierung auch entsprechend ohne obige C++-Regel erfolgreich kompilieren:
https://godbolt.org/z/GfYf3j4hY hat geschrieben:

Code: Alles auswählen

int foo()
{
    goto my_label;
    int x = 7;
my_label:
    return x;
}
Aber da man mit dem Überspringen der Initialisierung undefiniertes Verhalten hat (ist das tatsächlich eins?), macht der Compiler hier beliebiges und unerwartetes draus und aus der Funktion z.B. das Äquivalent eines return 0, siehe verlinkten Assembleroutput.

Meillo hat geschrieben: ↑ zum Beitrag ↑
03.09.2021 15:51:54
dakuan hat geschrieben: ↑ zum Beitrag ↑
03.09.2021 15:22:25
Ich denke, der Compiler macht sich das sehr einfach, indem er erstmal alles, was innerhalb des switch() Blocks als ein Scope sieht.
Das ist nunmal das Design von Switch in C/C++ ...
Durch die Tatsache, dass der switch-Block ein eigener Scope ist, lassen sich anscheinend lustige Dinge damit machen: Man kann eine Variable vor dem ersten Case deklarieren:
https://godbolt.org/z/dh96xPsfj hat geschrieben:

Code: Alles auswählen

int foo(int i)
{
    switch (i) {
        int x;
        case 0:
            x = 13;
            return x;
        default:
            x = 42;
            return x;
    }
}
Compiliert erfolgreich als C und C++. Man kann dort allerdings keinen Wert zuweisen, die Zeilen vor dem Case werden nie ausgeführt. Daher würd ich das nicht in ernsthaftem Code benutzen. Ich denke, es verwirrt die meisten Codeleser mehr, als dass es hilft.
Manchmal bekannt als Just (another) Terminal Hacker.

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: error: jump to case label

Beitrag von Meillo » 04.09.2021 14:21:42

JTH hat geschrieben: ↑ zum Beitrag ↑
04.09.2021 12:13:40
Meillo hat geschrieben: ↑ zum Beitrag ↑
03.09.2021 17:17:18
Wie dem auch sei. Mit meinem ``ich glaube, ich uebersehe etwas'' meine ich den Code von dakuan. Ich hatte nicht verstanden, welchen Grund der Compiler hat, diesen Fehler zu werfen.
[…]
Es gibt keinen sprachlichen Grund dafuer (was eben meine Frage war), […]
Doch, den gibt es tatsächlich. Es ist in C++, aber nicht in C, einfach ausdrücklich verboten, in den Gültigkeitsbereich einer Variablen über deren Deklaration hinweg hineinzuspringen:
https://en.cppreference.com/w/cpp/language/switch#Explanation hat geschrieben: Because transfer of control is not permitted to enter the scope of a variable, if a declaration statement is encountered inside the statement, it has to be scoped in its own compound statement:
Verbirgt sich im ISO-Standard anscheinend im Abschnitt zu Statements / Declaration statement. Da finde ich es aber nicht so leicht verständlich. Ein Hoch auf die Dokumentationen auf cppreference.com, die sind immer sehr hilfreich!
Vielen Dank fuer diese Info! ... und auch ueberhaupt fuer deinen ausfuehrlichen Post und die Recherche. :THX: (Zur Erklaerung: Ich programmiere nur C. Mir war nicht bewusst, dass es auf dieser tiefen Ebene auch solche Unterschiede gibt.)


Zu:
JTH hat geschrieben: ↑ zum Beitrag ↑
04.09.2021 12:13:40
Meillo hat geschrieben: ↑ zum Beitrag ↑
03.09.2021 17:17:18
[…] sondern das ist nur dem erzieherischen Element der Compilerentwickler geschuldet, das zunehmend um sich greift, wie mir scheint.
Ich finds mit Blick auf die Fehler durch uninitialisierte Variablen, die es mit C und C++ ja oft gibt, nicht verkehrt, dass so eine Problemquelle hier ausdrücklich nicht nur durch die Compilerentwickler, sondern sogar durch den Sprachstandard ausgeschlossen ist.

Eine – logische – Folge der Regel: Der Compilefehler kommt nur, wenn man mehr als einen Case hat. Denn mit nur einem Case gibt es letztendlich keinen Sprung. Folgendes kompiliert als C++:
https://godbolt.org/z/WeTGY8jh7 hat geschrieben:

Code: Alles auswählen

int foo(int x)
{
    switch (x) {
        case 0:
            int a = 42;
            return a;
    }

    return 0;
}
Mit einem zusätzlichen Case scheitert es dann wieder wie bekannt.
Und:
JTH hat geschrieben: ↑ zum Beitrag ↑
04.09.2021 12:13:40
Meillo hat geschrieben: ↑ zum Beitrag ↑
03.09.2021 15:51:54
dakuan hat geschrieben: ↑ zum Beitrag ↑
03.09.2021 15:22:25
Ich denke, der Compiler macht sich das sehr einfach, indem er erstmal alles, was innerhalb des switch() Blocks als ein Scope sieht.
Das ist nunmal das Design von Switch in C/C++ ...
Durch die Tatsache, dass der switch-Block ein eigener Scope ist, lassen sich anscheinend lustige Dinge damit machen: Man kann eine Variable vor dem ersten Case deklarieren:
https://godbolt.org/z/dh96xPsfj hat geschrieben:

Code: Alles auswählen

int foo(int i)
{
    switch (i) {
        int x;
        case 0:
            x = 13;
            return x;
        default:
            x = 42;
            return x;
    }
}
Compiliert erfolgreich als C und C++. Man kann dort allerdings keinen Wert zuweisen, die Zeilen vor dem Case werden nie ausgeführt. Daher würd ich das nicht in ernsthaftem Code benutzen. Ich denke, es verwirrt die meisten Codeleser mehr, als dass es hilft.
Diese zwei Beispiele, die du hier anfuehrst, zeigen aus meiner Sicht, dass es zwar eine nette Idee ist, dieses Problem mit dem Sprachstandard loesen zu wollen, sich dies damit in der Realitaet aber damit gar nicht erreichen laesst. Das Design von Switch laesst es nicht zu, dass man hier formal ansetzen kann, weil das Switch dafuer nicht strukturiert genug ist. Man kann es dann so sehen, dass es gut ist, wenn man wenigstens die haeufigsten Faelle abfaengt, oder man kann es schlecht finden, dass man den Sprachstandard aufblaeht ohne dass man das Problem damit wirklich loesen kann. Fuer mich wirkt es unstimmig, mit so harten Mitteln ein Problem anzugehen, das so weich ist. Ich finde, dass man die (aus heutiger Sicht dominierenden) Schwaechen des Switch und seines Design akzeptieren muss, statt sich schoenzureden, dass es anders waere oder man das formal reparieren koennte ohne sein Design zu aendern. Wenn man es richtig haette loesen wollen, dann haette man ein anderes Switch gebraucht. Aber nun gut, diese Zerrissenheit, zwischen C-Kompatibilitaet wahren und gegen dessen unerwuenschte Nachteile anzuarbeiten, sind ein Grund warum ich kein C++ programmiere.

Wenn man diese ganzen potenziellen Problemfaelle Warnings umsetzt, dann finde ich das sinnvoll. Wenn man daraus harte Fehler oder halblebige Loesungen im Sprachstandard macht, finde ich das weniger gut. Dein Beispiel zeigt ja schoen, wie man sich weiterhin in den Fuss schiessen kann ... waehrend der Sprachstandard in dem einen (noch nicht mal zwangslaeufig falschen) Fall den Eindruck erweckt, dass man die Probleme formal eingedaemmt haette. Das ist eine Unstimmigkeit, die ich nicht mag, weil ich dann nicht einschaetzen kann was ich zu erwarten habe. Ich werde immer wieder ueberrascht werden weil die Sprache eben unstimmig ist. Darum mag ich C so sehr: Dort weiss ich genau was ich zu erwarten habe, weil C eine so grosse Stimmigkeit im Sprachdesign hat.

JTH hat geschrieben: ↑ zum Beitrag ↑
04.09.2021 12:13:40
Meillo hat geschrieben: ↑ zum Beitrag ↑
03.09.2021 17:17:18
Hier ein Testprogramm, das zwar C-Code enthaelt aber mit g++ uebersetzt wird:
Wenn du den Code mit dem g++ kompilierst, ist es in dem Moment doch C++-Code und wird mit entsprechenden Regeln wie der obigen übersetzt. Gültig ist er ja in beiden Sprachen.
Damit hast du recht.
JTH hat geschrieben: ↑ zum Beitrag ↑
04.09.2021 12:13:40
Als C-Code würde dein (noch weiter) vereinfachtest Beispiel mit Überspringen der Variableninitialisierung auch entsprechend ohne obige C++-Regel erfolgreich kompilieren:
https://godbolt.org/z/GfYf3j4hY hat geschrieben:

Code: Alles auswählen

int foo()
{
    goto my_label;
    int x = 7;
my_label:
    return x;
}
Aber da man mit dem Überspringen der Initialisierung undefiniertes Verhalten hat (ist das tatsächlich eins?), macht der Compiler hier beliebiges und unerwartetes draus und aus der Funktion z.B. das Äquivalent eines return 0, siehe verlinkten Assembleroutput.
Hier machst du einen Fehler weil dein Beispiel *keine* Vereinfachung meines Beispiels ist, sondern einen ganz anderen Fall darstellt, bei dem ich den Fehler auch problemlos nachvollziehen kann. Dein Beispiel muss zurecht angemeckert werden, weil `x' im Return nicht bekannt sein kann, mein Beispiel und dekuans Code haben dieses Problem aber nicht. Sie sind aber von folgendem Schema:

Code: Alles auswählen

int foo()
{
    int y = 1;
    goto my_label;
    int x = 7;
    y = x;
my_label:
    return y;
}
D.h. es gibt keine Zugriffe auf Variablen deren Definition nicht erfolgt ist. Wuerde man den uebersprungenen Code entfernen, dann waere der Rest valide. Schaut man sich den uebersprungenen Code fuer sich genommen an, dann ist er ebenfalls valide.

Dein Beispiel muss vom Compiler abgelehnt werden, weil der Code nicht funktionieren kann; mein Beispiel kann kompiliert werden weil der Code durchaus problemlos funktioniert. (Einen Hinweis auf das *potenzielle* aber nicht zwangslaeufige Problem faende ich schon sinnvoll, aber das ist nebensaechlich.)


Hier nochmal meine Versuche zur Demonstration:

Code: Alles auswählen

:-Q cat c.c
#include <stdio.h>

int main(void)
{
    int y = 4;
    goto my_label;
    int x = 7;
    y = x;
my_label:
    return y;
}

:-Q c99 -Wall -Wextra -pedantic c.c -o c

:-Q ./c ; echo $?
4

:-Q rm c

:-Q g++ -Wall -Wextra -pedantic c.c -o c
c.c: In function ‘int main()’:
c.c:9:1: error: jump to label ‘my_label’ [-fpermissive]
c.c:6:10: error:   from here [-fpermissive]
c.c:7:9: error:   crosses initialization of ‘int x’

:-Q ./c ; echo $?
mksh: ./c: not found
127

:-Q 
Use ed once in a while!

dakuan
Beiträge: 97
Registriert: 28.04.2011 22:09:39

Re: error: jump to case label [gelöst]

Beitrag von dakuan » 04.09.2021 20:19:26

Eine – logische – Folge der Regel: Der Compilefehler kommt nur, wenn man mehr als einen Case hat. Denn mit nur einem Case gibt es letztendlich keinen Sprung. Folgendes kompiliert als C++:
Nicht ganz. In meinem Beispiel hatte ich ja de facto 2 Cases, wo das monatelang funktioniert hatte. Aber nur, weil die Definition im letzten Case statt fand.

Ich meine allerdings mal gelesen zu haben, dass der Compiler die Freiheit hat, die Cases anders anzuordnen. Aber ich glaube das sollten wir jetzt nicht weiter betrachten, Sonst werden wir noch als Erbsenzähler tituliert.

Das dieses Verhalten in der Norm so festgeschrieben ist, war mir allerdings auch neu.
Es ist in C++, aber nicht in C, einfach ausdrücklich verboten, in den Gültigkeitsbereich einer Variablen über deren Deklaration hinweg hineinzuspringen:
Ich stolpere auch immer wieder über diese feinen Unterschiede, besonders wenn ich Jahre alten C Code in C++ Methoden überführe.
Aber nun gut, diese Zerrissenheit, zwischen C-Kompatibilitaet wahren und gegen dessen unerwuenschte Nachteile anzuarbeiten, sind ein Grund warum ich kein C++ programmiere.
Ich bin ja eigentlich auch eher ein C-Programmierer. Aber wenn man eine GUI benötigt und sich mit SDL oder GTK nicht so recht anfreunden kann, muss man sich auch mit C++ beschäftigen. Aber die gefühlt jährlichen Erweiterungen machen C++ irgendwann zu einem unbeherrschbaren Monster. Aber ich muss ja nicht alle Neuerungen mitmachen.
Darum mag ich C so sehr: Dort weiss ich genau was ich zu erwarten habe, weil C eine so grosse Stimmigkeit im Sprachdesign hat.
Ja, C ist ziemlich geradlinig. Die Gegner sagen zwar immer, das man sich damit leicht ins Knie schießen kann, aber wer regelmäßig mit C unterwegs ist, bekommt schnell einen Blick für die Probleme.

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: error: jump to case label [gelöst]

Beitrag von Meillo » 04.09.2021 22:15:35

dakuan hat geschrieben: ↑ zum Beitrag ↑
04.09.2021 20:19:26
Eine – logische – Folge der Regel: Der Compilefehler kommt nur, wenn man mehr als einen Case hat. Denn mit nur einem Case gibt es letztendlich keinen Sprung. Folgendes kompiliert als C++:
Nicht ganz. In meinem Beispiel hatte ich ja de facto 2 Cases, wo das monatelang funktioniert hatte. Aber nur, weil die Definition im letzten Case statt fand.
Einfach grossartig! :-D
Use ed once in a while!

Antworten