Forum: Compiler & IDEs Warum doppelbedeutung static?


von Sina A. (sinapse)


Lesenswert?

Hallo,

in C hat ja static eine doppelbedeutung.

-bei lokalen variablen innerhalb von funktionsrümpfen wird eine variable 
statisch im speicher abgelegt und bleibt somit auch nach dem 
funktionsaufruf erhalten. hier hat "static" die bedeutung von 
"feststehend"

-bei funktionen/variablen wird mit static die sichtbarkeit auf die 
aktuelle übersetzungseinheit der funktion/variable beschränkt. warum zum 
teufel haben die macher von C hier auch das schlüsselwort 
static=feststehend verwendet???? das macht doch gar keinen sinn und 
führt zu verwirrung bei dieser doppelverwendung? oder findet irgendwas 
im hintergrund statt, das die bedeutung von static an dieser stelle 
erklärt??


mfg

: Verschoben durch User
von Return of Schnulli (Gast)


Lesenswert?

Sina stellte fest:
>..und führt zu verwirrung bei dieser doppelverwendung

Die Syntax dieser Sprache führt ohnehin oft zu Verwirrung und ist schwer
zu erlernen. Da kommt es auf diese Doppeldeutigkeit auch nicht mehr an.

von думлихер троль (Gast)


Lesenswert?

Kernziel und Sinn dieser Sprache ist maximale Verwirrung fuer minimale 
Produktivitaet. Motto : wie kann man einen Job in die Laenge ziehen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Return of Schnulli schrieb:
> Die Syntax dieser Sprache führt ohnehin oft zu Verwirrung und ist schwer
> zu erlernen. Da kommt es auf diese Doppeldeutigkeit auch nicht mehr an.
Man stelle sich vor, es gibt Programmiersprachen, da hat sogar schon ein 
simples Gleichheitszeichen eine mehrfache Bedeutung, die sich nur aus 
dem Kontext erschließt...

Mit B=3 ist je nach Positionierung etwas anderes als B=3 gemeint:
1
   B=3;
2
   
3
   if B=3 then ...

: Bearbeitet durch Moderator
von Olaf (Gast)


Lesenswert?

> das macht doch gar keinen sinn und
> führt zu verwirrung bei dieser doppelverwendung?

Wir C-Programmier wollen halt nicht das sich jeder Schnullerbubi 
Programmierer schimpfen kann. :-)

Olaf

von Peter II (Gast)


Lesenswert?

ist doch ganz einfach - man muss weniger Schlüsselworte lernen.

auch die Buchstaben haben in C oft eine mehrfache Verwendung: "i" wird 
in if und while verwendet.

von Ulrich (Gast)


Lesenswert?

Im Kern ist das static in beiden Fällen die Ansage, dass der Compiler 
direkt eine feste Adresse benutzen soll. Bei einer Funktion hat das dann 
die Folge, das der Linker die Funktion nicht mehr bearbeitet und externe 
die nicht nutzen können. Für eine Variable ist der Nebeneffekt halt dass 
der Wert erhalten bleibt.

Das kommt hat weil C eine alte Hardware nahe Sprache ist, mehr von der 
ASM Seite gewachsen als als Hochsprache geplant.

von Jens K. (blauzahnmeister)


Lesenswert?

wem das nicht reicht, dem empfehle ich die Sprache Brainfu*ck

von Sina A. (sinapse)


Lesenswert?

ahhh.... super, genau das wollte ich wissen... daaanke

lg

von Peter D. (peda)


Lesenswert?

Es gibt schlimmere Doppelbelegungen.

Z.B. wenn man eine Schleife verlassen will, geht das mit Break.
Hat man mehrere Abbruchbedingungen, würde sich ein Switch geradezu 
anbieten und wäre auch am besten lesbar.
Dummm nur, daß dann das Break nicht die Schleife verläßt.
Hier kann man nur ein Goto zum Verlassen benutzen.

von Random .. (thorstendb) Benutzerseite


Lesenswert?

... dann gibt es noch die Variante in C++, hier haben alle Instanzen 
Zugriff auf die gleiche static variable innerhalb einer 
member-funktion :-)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

sina anargo schrieb:
> warum zum teufel haben die macher von C hier auch das schlüsselwort
> static=feststehend verwendet?

Warum zum Teufel ist „modul-lokal“ nicht die voreingestellte
Sichtbarkeitsregel?  Dann hätte man “global” als Schlüsselwort für
solche Daten und Funktionen festlegen können, die auch außerhalb der
aktuellen Übersetzungseinheit sichtbar sein müssen.

Die Antwort ist ganz einfach: historischer Ballast.

von Andreas D. (rackandboneman)


Lesenswert?

@dl8dtl modul-lokal in einer Sprache in der Module allenfalls als 
Toolchain-Konzept aber nicht wirklich als Sprachkonstrukt vorkommen? 
Klingt riskant...

von Marc P. (marcvonwindscooting)


Lesenswert?

Verminderung der Namensraumverschmutzung. Jedes der Schluesselworte 
faellt aus der Menge der moeglichen Bezeichner heraus -> nicht gut.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

sina anargo schrieb:
> in C hat ja static eine doppelbedeutung.

Das sieht nur auf den ersten Blick so aus. Beide Deiner Beschreibungen 
passen sowohl bei lokalen als auch bei globalen:

1. Beide Variablen-Typen sind "feststehend", liegen also nicht auf dem
   Stack oder Heap.

2. Beide Typen sind "von außen" nicht sichtbar.

Da ist also gar keine Doppelbedeutung, wenn man etwas länger drüber 
nachdenkt.

: Bearbeitet durch Moderator
von Bücherwurm (Gast)


Lesenswert?

kauft Euch ein C-Buch!

von Mike Roh (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Dummm nur, daß dann das Break nicht die Schleife verläßt.
> Hier kann man nur ein Goto zum Verlassen benutzen.

Oder einfach 'continue' ?

von Sebastian Hepp (Gast)


Lesenswert?

Continue verlässt die Schleife aber nicht, sondern führt die nächste 
Iteration aus

von Mike Roh (Gast)


Lesenswert?

1
while (1) 
2
{
3
...
4
    switch(state) 
5
    {
6
    case STAY
7
        ...
8
        continue;
9
    case DONE:
10
        break;
11
    default:
12
        break;
13
    }
14
    break;
15
}

Alles nur kein GOTO :P

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Andy D. schrieb:
> @dl8dtl modul-lokal in einer Sprache in der Module allenfalls als
> Toolchain-Konzept aber nicht wirklich als Sprachkonstrukt vorkommen?
> Klingt riskant...

hä? In C heißt das eben anders, z.b. "internal linkage" und "translation 
unit" etc.

Siehe 6.2.2 Linkages of Identifiers.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Mike Roh schrieb:
>
1
> while (1)
2
> {
3
> ...
4
> }
5
>
>
> Alles nur kein GOTO :P

Peter meinte eine Schleife mit echter Abbruchbedingung - darin ein 
switch. Man kann die Schleife innerhalb des Switches entweder mit einem 
goto verlassen oder ... so mache ich das meist ... vor dem break dafür 
sorgen, dass die Bedingung der Schleife nicht mehr erfüllt ist.

Gruß,

Frank

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Ulrich schrieb:
> Im Kern ist das static in beiden Fällen die Ansage, dass der Compiler
> direkt eine feste Adresse benutzen soll. Bei einer Funktion hat das dann
> die Folge, das der Linker die Funktion nicht mehr bearbeitet und ...

Käse :-) Der Compiler hat mit Adressvergabe grad garnix am Hat, das 
macht immer noch der Linker / Lokator, im Fall der GCC also ld.

von Rolf Magnus (Gast)


Lesenswert?

Random ... schrieb:
> ... dann gibt es noch die Variante in C++, hier haben alle Instanzen
> Zugriff auf die gleiche static variable innerhalb einer
> member-funktion :-)

Und dann gibt's auch noch Member-Funktionen, die static sind.

Frank M. schrieb:
> sina anargo schrieb:
>> in C hat ja static eine doppelbedeutung.
>
> Das sieht nur auf den ersten Blick so aus. Beide Deiner Beschreibungen
> passen sowohl bei lokalen als auch bei globalen:
>
> 1. Beide Variablen-Typen sind "feststehend", liegen also nicht auf dem
>    Stack oder Heap.

Das tut eine Variable außerhalb der Funktion auch ohne static.

> 2. Beide Typen sind "von außen" nicht sichtbar.

Das ist bei lokalen Variablen aber immer so und kommt ebenfalls nicht 
erst durch static.

> Da ist also gar keine Doppelbedeutung, wenn man etwas länger drüber
> nachdenkt.

Und wenn man noch etwas länger drüber nachdenkt, ist doch eine da. ;-)

von Mike Roh (Gast)


Lesenswert?

Johann L. schrieb:
> Ulrich schrieb:
>> Im Kern ist das static in beiden Fällen die Ansage, dass der Compiler
>> direkt eine feste Adresse benutzen soll. Bei einer Funktion hat das dann
>> die Folge, das der Linker die Funktion nicht mehr bearbeitet und ...
>
> Käse :-) Der Compiler hat mit Adressvergabe grad garnix am Hat, das
> macht immer noch der Linker / Lokator, im Fall der GCC also ld.

Das ist nicht ganz richtig. Der Compiler könnte static Funktionen z.b. 
inlinen.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Rolf Magnus schrieb:
>> Da ist also gar keine Doppelbedeutung, wenn man etwas länger drüber
>> nachdenkt.
>
> Und wenn man noch etwas länger drüber nachdenkt, ist doch eine da. ;-)

Welche denn? Die beiden im Ausgangsposting genannten jedenfalls nicht. 
Denn diese treffen für beide Typen von static-Variablen zu.

Auch Deine (natürlich korrekte) Aussage

> Das tut eine Variable außerhalb der Funktion auch ohne static.

ist für mich kein wirklicher Widerspruch.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Mike Roh schrieb:
> Johann L. schrieb:
>> Ulrich schrieb:
>>> Im Kern ist das static in beiden Fällen die Ansage, dass der Compiler
>>> direkt eine feste Adresse benutzen soll. Bei einer Funktion hat das dann
>>> die Folge, das der Linker die Funktion nicht mehr bearbeitet und ...
>>
>> Käse :-) Der Compiler hat mit Adressvergabe grad garnix am Hat, das
>> macht immer noch der Linker / Lokator, im Fall der GCC also ld.
>
> Das ist nicht ganz richtig. Der Compiler könnte static Funktionen z.b.
> inlinen.

Was aber nix mit Adressvergabe zu tun hat, sondern damit, ob er die 
Implementierung der Funktion kennt oder nicht.  Er kann auch extern 
Funktionen inlinen, etwa mit Optimierungen wie LTO.  Auch das hat im 
Kern nix mit Adressvergabe zu tun.  Der Compiler vergibt keine 
Adressen.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Im Ur-C-Compiler für Unix war der "static"-Qualifier lokalen Variablen
vorbehalten, wo er festlegt, dass die Lebensdauer einer Variable im
Gegensatz zu "auto" nicht auf die Dauer der Funktionsausführung
beschränkt sein soll.

Globale Variablen mit "static" gab es nicht, was ja auch logisch ist, da
globale Variablen in C immer statisch sind.

Es entstand neben dem Unix-C-Compiler noch einer für GCOS, der bereits
die spezielle Bedeutung von "static" für globale Variablen implementiert
hatte. Dass für dieses Feature ein bereits vorhandenes Schlüsselwort
genutzt wurde, hatte den Vorteil, dass der GCOS-Compiler (zumindest in
dieser Punkt) abwärtskompatibel zum Unix-Compiler war.

Später wurde dieses Feature dann auch in den Unix-Compiler übernommen,
zusammen mit der Möglichkeit, statische lokale Veriablen initialisieren
zu können, was vorher mit dem Unix-Compiler ebenfalls nicht möglich war.

von Peter D. (peda)


Lesenswert?

Noch ne Doppelfunktion:
1
  int * x = 5;
2
3
      * x = 6;

Einmal Adresse 5 und einmal Wert 6.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Andy D. schrieb:
> modul-lokal in einer Sprache in der Module allenfalls als
> Toolchain-Konzept aber nicht wirklich als Sprachkonstrukt vorkommen?

Dann nenne es „lokal zur Übersetzungseinheit“, wenn dir das Wort besser
als „Modul“ gefällt.

Yalu X. schrieb:
> Es entstand neben dem Unix-C-Compiler noch einer für GCOS, der bereits
> die spezielle Bedeutung von "static" für globale Variablen implementiert
> hatte.

Sag ich doch, historischer Ballast. :-)

von Takao K. (takao_k) Benutzerseite


Lesenswert?

Return of Schnulli schrieb:
> Sina stellte fest:
>>..und führt zu verwirrung bei dieser doppelverwendung
>
> Die Syntax dieser Sprache führt ohnehin oft zu Verwirrung und ist schwer
> zu erlernen. Da kommt es auf diese Doppeldeutigkeit auch nicht mehr an.

Ja eine gewisse Barriere gibt es schon um C zu lernen.

Wenn man weiss was man erreichen will, gibts auch keine Verwirrung.

Must du halt lernen wie es verwendet wirdt.

von Takao K. (takao_k) Benutzerseite


Lesenswert?

Mike Roh schrieb:
>
1
> while (1)
2
> {
3
> ...
4
>     switch(state)
5
>     {
6
>     case STAY
7
>         ...
8
>         continue;
9
>     case DONE:
10
>         break;
11
>     default:
12
>         break;
13
>     }
14
>     break;
15
> }
16
>
>
> Alles nur kein GOTO :P

wieso denn nicht? Ich finde GOTO gut. Wird ja ohnehin in ein GOTO (JMP) 
uebersetzt auf assemblerebene.

ein seitenlanges switch statement mit breaks ist auch unuebersichtlich. 
In Turbo Basic war SELECT CASE ein richtiges Schnuerkorsett.

von Takao K. (takao_k) Benutzerseite


Lesenswert?

Peter Dannegger schrieb:
> Es gibt schlimmere Doppelbelegungen.
>
> Z.B. wenn man eine Schleife verlassen will, geht das mit Break.
> Hat man mehrere Abbruchbedingungen, würde sich ein Switch geradezu
> anbieten und wäre auch am besten lesbar.
> Dummm nur, daß dann das Break nicht die Schleife verläßt.
> Hier kann man nur ein Goto zum Verlassen benutzen.

Die richtig notorischen C programmierer schreiben eine Schleife ohne for 
zu verwenden, also z.B.
1
reloop:;i=0;mach_was();
2
if((i++)<10)goto reloop;

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Takao K. schrieb:
> Die richtig notorischen C programmierer

Real programmers can write FORTRAN programs in any language …

von W.S. (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Dann nenne es „lokal zur Übersetzungseinheit“, wenn dir das Wort besser
> als „Modul“ gefällt.

Ach Jörg, laß dich nicht foppen.
Es gibt halt mittlerweile zu wenige Leute, die des Pascales noch mächtig 
sind. Dort braucht man keine Headerdateien, dort kann man dediziert in 
der Quelle festlegen, welche Dinge des Moduls (oder nennen wir es 
einfach wieder "UNIT" - dieses Wort gefällt mir sowieso besser) von 
außen sichtbar sein sollen und welche nicht. Obendrein kann man dort 
Variablen mit feststehender Adresse ('absolute') vereinbaren. Das wäre 
wesentlich schicker und lesbarer als das Geprassel, was man sich bei µC 
in C antun muß, um eines der Hardware-Register zu beschreiben.

Man hätte C schon längst reformieren können, anstatt immer noch eine 
Version draufzusetzen. Aber seit dem Übergang von K&R nach ANSI ist den 
Gremien wohl die Puste ausgegangen.

Tja, mal wieder das alte Thema..


W.S.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

W.S. schrieb:
> welche Dinge des Moduls

Das mit den Modulen war Modula. ;-)

von Takao K. (takao_k) Benutzerseite


Lesenswert?

W.S. schrieb:
> Jörg Wunsch schrieb:
>> Dann nenne es „lokal zur Übersetzungseinheit“, wenn dir das Wort besser
>> als „Modul“ gefällt.
>
> Ach Jörg, laß dich nicht foppen.
> Es gibt halt mittlerweile zu wenige Leute, die des Pascales noch mächtig
> sind. Dort braucht man keine Headerdateien, dort kann man dediziert in
> der Quelle festlegen, welche Dinge des Moduls (oder nennen wir es
> einfach wieder "UNIT" - dieses Wort gefällt mir sowieso besser) von
> außen sichtbar sein sollen und welche nicht. Obendrein kann man dort
> Variablen mit feststehender Adresse ('absolute') vereinbaren. Das wäre
> wesentlich schicker und lesbarer als das Geprassel, was man sich bei µC
> in C antun muß, um eines der Hardware-Register zu beschreiben.
>
> Man hätte C schon längst reformieren können, anstatt immer noch eine
> Version draufzusetzen. Aber seit dem Übergang von K&R nach ANSI ist den
> Gremien wohl die Puste ausgegangen.
>
> Tja, mal wieder das alte Thema..
>
>
> W.S.

Also ich finde C gut.

mach doch mal einen Typ Cast in Pascal- es geht zwar, allerdings toll 
ist es nicht gerade.

Ich finde C gut da ich es fast genauso wie Assembler verwenden kann.

Es gibt unions und es gibt Funktionszeiger. Deklariere doch mal in 
Pascal ein Array mit funktionszeigern...

Und ja, es gibt Anwendungen dafuer.

von W.S. (Gast)


Lesenswert?

Takao K. schrieb:
> Es gibt unions und es gibt Funktionszeiger. Deklariere doch mal in
> Pascal ein Array mit funktionszeigern...

Hä?
Wo lebst du?

Also
Erstens: Sowas wie unions gibt es auch in Pascal, nämlich records mit 
variablem Innenleben.

Zweitens: Typecasts gibt es auch, wird aber wesentlich seltener benötigt 
als in C und ist einleichtender: typebezeichner(operand).
function MyThreadProc(zahl:Pointer):longint;
begin
  if (dword(zahl) and 16) <> 0 then blablabla..


Drittens:Funktionszeiger gibt es natürlich auch:

type
 TWriter = procedure(S : String);
 TReader = function : char;

var
 MyWriter : TWriter;
 MyReader : TReader;

Man kann dann, nachdem man den entsprechenden Funktionspointer in 
MyReader und MyWriter eingetragen hat, MyReader und MyWriter wie normale 
Prozeduren bzw. Funktionen aufrufen.

begin
  MyReader:= @UART_In;
  MyWriter:= @Drucker_Output;

  c:= MyReader;
  MyWriter('Hallo');

Also, wo ist dein Problem? Offenbar nur dieses, daß du Pascal nicht so 
recht kennst.

W.S.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

W.S. schrieb:
> Sowas wie unions gibt es auch in Pascal, nämlich records mit variablem
> Innenleben.

Mit dem Unterschied, dass man den Varianten-Selektor dort zwangsweise
als Bestandteil des Varianten-Records mit angeben muss, zumindest in
Standard-Pascal.

Pascal ist halt als Lehrsprache entwickelt worden und von da dann
aufgebohrt, wobei die einzelnen Hersteller nicht alle den gleichen
Bohrer benutzt haben. ;-)  Herr Wirth wollte das dann mit Modula
wieder ausgleichen, was aber bei weitem nicht die Verbreitung
gefunden hat, die er sich gewünscht haben mag.

von Takao K. (takao_k) Benutzerseite


Lesenswert?

Jörg Wunsch schrieb:
> W.S. schrieb:
>> Sowas wie unions gibt es auch in Pascal, nämlich records mit variablem
>> Innenleben.
>
> Mit dem Unterschied, dass man den Varianten-Selektor dort zwangsweise
> als Bestandteil des Varianten-Records mit angeben muss, zumindest in
> Standard-Pascal.
>
> Pascal ist halt als Lehrsprache entwickelt worden und von da dann
> aufgebohrt, wobei die einzelnen Hersteller nicht alle den gleichen
> Bohrer benutzt haben. ;-)  Herr Wirth wollte das dann mit Modula
> wieder ausgleichen, was aber bei weitem nicht die Verbreitung
> gefunden hat, die er sich gewünscht haben mag.

PASCAL ist keine wirklich neue Sprache, hat der Herr Wirth von PL/1 
abgekupfert. habe mich jahrelang damit abgegeben und oft hatte ich halt 
Ideen, wurde aber von der Syntax eingeschraenkt.

Und es hat halt den ruf einer Hobby und Bastelsprache.

richtig eklig wird es wenn in Pascal pointer zusammengebaut werden 
sollten. In C ist es schon schlimm genug.
1
curr_chr_size2_ptr=&alpha_chr[chr_curr];
2
curr_chr_size2=*curr_chr_size2_ptr;
3
lvl2= ((const char*)
4
(
5
(*curr_chr_size2_ptr)
6
|
7
(
8
((unsigned int)(*(curr_chr_size2_ptr+1))) << 8)
9
)
10
);
11
12
curr_chr_size2=*((const char*)(lvl2));

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Takao K. schrieb:

> PASCAL ist keine wirklich neue Sprache, hat der Herr Wirth von PL/1
> abgekupfert.

Ich hätte jetzt eher auf Algol (60/68) getippt.

> Und es hat halt den ruf einer Hobby und Bastelsprache.

Naja, sowas ist nicht unumstößlich.  Ich habe zu CP/M-Zeiten gern in
Turbo-Pascal programmiert, denn die Programmierumgebung war angenehm
zu bedienen und recht flott (anders als die meisten C-Compiler und
auch alternative Pascal-Implementierungen damals), und man hatte
gegenüber Assembler den Vorteil einer deutlich effektiveren (bezüglich
des zu spendierenden Zeitaufwands) Programmierung.  Als der EPROMmer
dann erstmal grundsätzlich lief, habe ich die innere Schleife in
Inline-assembler nachgeschrieben.  Danach war es sowohl schnell als
auch gut bedienbar.

von Takao K. (takao_k) Benutzerseite


Lesenswert?

Jörg Wunsch schrieb:
> Takao K. schrieb:
>
>> PASCAL ist keine wirklich neue Sprache, hat der Herr Wirth von PL/1
>> abgekupfert.
>
> Ich hätte jetzt eher auf Algol (60/68) getippt.
>
>> Und es hat halt den ruf einer Hobby und Bastelsprache.
>
> Naja, sowas ist nicht unumstößlich.  Ich habe zu CP/M-Zeiten gern in
> Turbo-Pascal programmiert, denn die Programmierumgebung war angenehm
> zu bedienen und recht flott (anders als die meisten C-Compiler und
> auch alternative Pascal-Implementierungen damals), und man hatte
> gegenüber Assembler den Vorteil einer deutlich effektiveren (bezüglich
> des zu spendierenden Zeitaufwands) Programmierung.  Als der EPROMmer
> dann erstmal grundsätzlich lief, habe ich die innere Schleife in
> Inline-assembler nachgeschrieben.  Danach war es sowohl schnell als
> auch gut bedienbar.

Zugegeben, als ich Schueler war in der Realschule, konnte ich mit C 
nicht viel anfangen. Das war installiert auf den Rechnern, aber zum 
Kompilieren mussten halt bestimmte Einstellungen gemacht werden. 
Internet oder Handbuecher gabs damals nicht.

Bei Turbo Pascal war ja eine Hilfefunktion dabei.

Habe ich dann z.B. verkettete Liste programmiert, und auch OOP 
ausprobiert. Dann Mitte der 1990er bin ich auf Assembler umgestiegen- da 
war halt das Schnuerkorsett weg.

Wenn ich mir Pascal Programme heute mal anschaue, moechte ich das 
garnicht mehr machen.

Heutzutage gibts ja internet, es ist viel einfacher eine Antwort auf ein 
bestimmtes Verstaendnissproblem zu erhalten.

Wenn C erst einmal richtig verstanden wird, ist es sehr leistungsfaehig 
und die Art und Weise von Deklarierungen, Addressierung usw. ist sehr 
praktisch.

z.B. mit MPLABX, gibt es Autocomplete fuer Strukturen, und Variablen 
einfach im Debugger anzeigen (auch fuer Array/Strukture).

Das gabs 1990 nicht. So kann C dann auch recht schnell erlernt werden.

von anti c (Gast)


Lesenswert?

Lothar Miller schrieb:

Auch wenn es schlimmeres gibt, macht es das Krücken C nicht besser.

von anti c (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Es gibt schlimmere Doppelbelegungen.
>
> Z.B. wenn man eine Schleife verlassen will, geht das mit Break.
> Hat man mehrere Abbruchbedingungen, würde sich ein Switch geradezu
> anbieten und wäre auch am besten lesbar.
> Dummm nur, daß dann das Break nicht die Schleife verläßt.
> Hier kann man nur ein Goto zum Verlassen benutzen.

Break und goto arbeiten unterschiedlich. Das ist dir schon bekannt, 
oder?

Wer goto braucht, kann nicht programmieren. :-P

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

anti c schrieb:
> Wer goto braucht, kann nicht programmieren.

Ist auch mit Smiley eine unsinnige Aussage.

Kennst du Donald Knuth?  Er hat mal einen Aufsatz geschrieben
"Structured Programming with Go To".  Das war sein Protest gegen
Dijkstras dogmatisch gepredigten Verzicht auf goto.

von Takao K. (takao_k) Benutzerseite


Lesenswert?

Jörg Wunsch schrieb:
> anti c schrieb:
>> Wer goto braucht, kann nicht programmieren.
>
> Ist auch mit Smiley eine unsinnige Aussage.
>
> Kennst du Donald Knuth?  Er hat mal einen Aufsatz geschrieben
> "Structured Programming with Go To".  Das war sein Protest gegen
> Dijkstras dogmatisch gepredigten Verzicht auf goto.

Also ich will es garnicht mutmassen was Herr D. so privat macht wass Ihn 
in die Lage versetzt solch ein Pamphlet anzufertigen.

Koennte ein Fall sein von "Ich will es garnicht wissen mir reicht schon 
was ich sehe".

Und 20 Jahre spaeter dann so ein Krampf ein jeder plappert es nach, ja 
nicht auch nur ein GOT0 verwenden oder Bestien aus dem Hades werden sich 
manifestieren.

Es ist total egal- im Endeffekt gibt es einen Assembler mit Switch 
Opcodes nicht. Nach einem Vergleich wird ja ohnehin ein GOTO verwendet 
wie sollte es anders gehen? Es wird halt nur nicht ausgeschrieben.

Aus so einem Grund ist dieses Pamphlet halt ein Krampf.

von anti c (Gast)


Lesenswert?

Von mir aus kann auch Donald Duck was dazu schreiben. Das goto zerstört 
den Programmfluss und macht die Software unübersichtlich. Im 
Profibereich also ein no go.

von Takao K. (takao_k) Benutzerseite


Lesenswert?

anti c schrieb:
> Peter Dannegger schrieb:
>> Es gibt schlimmere Doppelbelegungen.
>>
>> Z.B. wenn man eine Schleife verlassen will, geht das mit Break.
>> Hat man mehrere Abbruchbedingungen, würde sich ein Switch geradezu
>> anbieten und wäre auch am besten lesbar.
>> Dummm nur, daß dann das Break nicht die Schleife verläßt.
>> Hier kann man nur ein Goto zum Verlassen benutzen.
>
> Break und goto arbeiten unterschiedlich. Das ist dir schon bekannt,
> oder?
>
> Wer goto braucht, kann nicht programmieren. :-P

Was mir selbst zu eigen ist unterstelle ich halt anderen, um davon 
abzulenken. Da wird aus dem Rowdy in der Schule der dich schikaniert 
halt ein "Beschuetzer", er will dich ja nur abhaerten und er tut es nur 
damit es andere nicht tun.

Alles Mueller oder was.

von Takao K. (takao_k) Benutzerseite


Lesenswert?

anti c schrieb:
> Von mir aus kann auch Donald Duck was dazu schreiben. Das goto zerstört
> den Programmfluss und macht die Software unübersichtlich. Im
> Profibereich also ein no go.

Kannste darueber lachen wenn du dir die Disassemblierung anschaust. Es 
zerstoert den Programfluss. Also wo denn, im Geiste?

Wenn du verschachtelte switch statements hast, und dann break 
verwendest, musst du es halt schoen abarbeiten und viel Spass dabei.

SWITCH erst garnicht verwenden.

Wenn es nur bis zu 5 Vergeleiche sind, einfach mit IF abfragen ansonsten 
einen Parser mit Tabelle verwenden.

von anti c (Gast)


Lesenswert?

Keiner pflegt ein Programm mit dem Disasm. Es geht um den reinen C Code.

Foto ist böse, Foto ist sch.......leicht.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

anti c schrieb:
> Von mir aus kann auch Donald Duck was dazu schreiben.

Nun, mit derart Überheblichkeit wirst du nicht weit kommen.  Du
verspottest etwas, ohne es dir überhaupt angesehen zu haben.

> Das goto zerstört
> den Programmfluss und macht die Software unübersichtlich. Im
> Profibereich also ein no go.

Beides Unsinn.

Lassen wir das.  Wir werden uns nicht einigen: ich kenne Knuths Gründe
(und nicht mehr alle davon stimmen heutzutage), und ich weiß, wann ich
selbst auch mal ein goto benutzen würde und wann lieber nicht.

Übrigens: wenn du kein goto benutzen willst, dann musst du auch unter
allen Umständen und komplett dogmatisch auf ein explizites "return"
aus einer Funktion verzichten (ausgenommen ganz am Ende).  Das ist
nämlich auch nur ein verkapptes "goto".  (Pascal hat sowas schließlich
auch nicht. ;-)

von Visualdingens (Gast)


Lesenswert?

Jörg Wunsch (dl8dtl) (Moderator) schrieb:

anti c schrieb:
>> Von mir aus kann auch Donald Duck was dazu schreiben.

> Nun, mit derart Überheblichkeit wirst du nicht weit kommen.  Du
> verspottest etwas, ohne es dir überhaupt angesehen zu haben.

Wahrscheinlich ist "anti c" nur ein verkanntes, unbekanntes Genie und 
kann einiges mehr vorweisen, als "die paar Werke", die der "nur" 
Stanford Prof. Donald E. Knuth, Autor des Standardwerks "The Art of 
Computer Programming" sowie Urvater des Textsatzsystems TeX beigesteuert 
hat, siehe

http://de.wikipedia.org/wiki/Donald_E._Knuth

Und als "anti c" wird er mit Freude und Wonne den Pascal Code im 
angesprochenen Machwert über das "Pöse goto" förmlich in sich aufsaugen

http://cs.sjsu.edu/~mak/CS185C/KnuthStructuredProgrammingGoTo.pdf

und seine Bildungslücken damit eventuell ein wenig aufpolieren.

Achja, ich hab das goto Paper übrigens auch nicht gelesen. Dafür aber 
u.A. das ein- oder andere TeX Buch mal von ihm gekauft und gelesen 
(laaange her).

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Jörg Wunsch schrieb:
> Real programmers can write FORTRAN programs in any language …

To compile DO loops like god meant them to be.

von anti c (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Übrigens: wenn du kein goto benutzen willst, dann musst du auch unter
> allen Umständen und komplett dogmatisch auf ein explizites "return" aus
> einer Funktion verzichten (ausgenommen ganz am Ende).  Das ist nämlich
> auch nur ein verkapptes "goto".  (Pascal hat sowas schließlich auch
> nicht. ;-)

Ob Fortran oder Pascal irgendetwas haben oder nicht, spielt doch keine 
Rolle. Ein goto ist in jeder Sprache Mist!

Übrigens: gibt es einen großen Unterschied zwischen return und goto. 
Beim return weiss man genau wo es landet. In Unterprogrammen werden 
garantiert stack und Register nach return restauriert. Beim goto ist das 
Staunen des super spitzen Programmierers garantiert, wenn er damit wild 
durchs Programm springt.
Ein guter Programmierer braucht kein goto! Es gibt keinen Fall, den man 
nicht genauso gut und viel besser nachvollziehbar hin bekommt.

Nur weil es diesen Befehl gibt, muss er nicht sinnvoll sein und genutzt 
werden. :-P

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

anti c schrieb:
> Ob Fortran oder Pascal irgendetwas haben oder nicht, spielt doch keine
> Rolle. Ein goto ist in jeder Sprache Mist!

Hast du das in der Schule / auf der Uni gelernt, oder sprichst du aus 
Erfahrung?

Jeder gute, weise und erfahrene Programmierer wird dir sagen, dass deine 
Pauschalaussage falsch ist.

Es gibt Fälle, wo ein goto sehr sinnvoll ist, den Programmfluss und die 
Intention des Programmierers viel klarer hervortreten lässt, und 
nebenbei noch viel ressourcenschonender ist.

Aber dazu gehört eben Erfahrung, viel (extrem viel) Code lesen und 
verstehen.

Aber natürlich ist es viel einfacher, "goto ist böse" nachzuplappern...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Michael Reinelt schrieb:
> Jeder gute, weise und erfahrene Programmierer wird dir sagen, dass deine
> Pauschalaussage falsch ist.

Schon deshalb, weil man in FORTRAN (zumindest bis F77) praktisch nicht
ohne GOTO auskam. ;-)

anti c schrieb:
> Nur weil es diesen Befehl gibt, muss er nicht sinnvoll sein und genutzt
> werden. :-P

Nur, weil du mal gehört hast, dass er böse wäre, heißt das noch lange
nicht, dass es keine sinnvollen Einsatzfälle dafür gäbe.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Jörg Wunsch schrieb:
> Schon deshalb, weil man in FORTRAN (zumindest bis F77) praktisch nicht
> ohne GOTO auskam. ;-)

Und, stell dir vor, ich hab mein ganzes Leben lang (leider) nie FORTRAN 
programmiert, und trotzdem verteidige ich das GOTO :-)

von anti c (Gast)


Lesenswert?

Ich spreche aus Erfahrung.

Und wie schon geschrieben: Es gibt keinen Fall, der nicht ohne goto für 
die Nachwelt besser verständlich und nachvollziehbar ist.

Natürlich kann man mit einem goto aus einer for Schleife springen. Das 
ist einfach und überschaubar. Aber das geht mit einem break genauso gut. 
Goto ist mächtig und erlaubt Sprünge quer durchs Programm. Das ist 
gefährlich und bei einer vernünftigen Programmstruktur völlig unnötig.

Ich bleigbe dabei: goto ist gefährlich und überflüssig!

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

anti c schrieb:
> Ich spreche aus Erfahrung.
Ah! Dann solltest dir vielleicht einen seriöseren Nick zulegen? Deiner 
klingt jetzt nicht grad nach 15 Jahren Programmiererfahrung und >1Mio 
LOC

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Michael Reinelt schrieb:
> Und, stell dir vor, ich hab mein ganzes Leben lang (leider) nie FORTRAN
> programmiert

Hast du nichts verpasst. :-)

anti c schrieb:
> Und wie schon geschrieben: Es gibt keinen Fall, der nicht ohne goto für
> die Nachwelt besser verständlich und nachvollziehbar ist.

Doch, gibt es.  Aber die willst du ja gar nicht wissen.

von Peter D. (peda)


Lesenswert?

Am besten auf Goto, Return verzichten und dafür Longjmp benutzen.
Dann kann man sogar zwischen Interrupts und Funktionen hin und her 
springen.

von anti c (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> anti c schrieb:
> Und wie schon geschrieben: Es gibt keinen Fall, der nicht ohne goto für
> die Nachwelt besser verständlich und nachvollziehbar ist.
>
> Doch, gibt es.  Aber die willst du ja gar nicht wissen.

Bla blab bla, wo ist den der Stein der Weisen?

von Takao K. (takao_k) Benutzerseite


Lesenswert?

anti c schrieb:
> Ich spreche aus Erfahrung.
>
> Und wie schon geschrieben: Es gibt keinen Fall, der nicht ohne goto für
> die Nachwelt besser verständlich und nachvollziehbar ist.
>
> Natürlich kann man mit einem goto aus einer for Schleife springen. Das
> ist einfach und überschaubar. Aber das geht mit einem break genauso gut.
> Goto ist mächtig und erlaubt Sprünge quer durchs Programm. Das ist
> gefährlich und bei einer vernünftigen Programmstruktur völlig unnötig.
>
> Ich bleigbe dabei: goto ist gefährlich und überflüssig!

also mit deinem Sprachgebrauch hast du wohl mal ein Beratungsgespraech 
noetig.

Goto ist mächtig

Nee ist es nicht.

und erlaubt Sprünge quer durchs Programm

Ja klar aber wer will das wirklich?

Vielleicht siehst du es ein dass der Compiler aus dem C Source ein 
Assembler programm erzeugt, und dass ist voll mit GOTOs.

Wie sollte denn ein IF funtionieren wenn nicht mit GOTO? Es ist nur eine 
andere Schreibweise.

CMP Register, Value

JNE Do_Something1

// Do_Something2

JMP Ready

Do_Something1:

// something

Ready:


Oder willst du est abstreiten dass die CPU genau dass macht?

if (var=value)
{
 do_something();
} else
{
 do_something2();
}


ein Lastwagen mit 80 KMH auf der Autobahn ist auch gefaehrlich.

: Bearbeitet durch User
von Visualdingens (Gast)


Lesenswert?

anti c (Gast) schrieb:

Jörg Wunsch schrieb:
>> anti c schrieb:
>> Und wie schon geschrieben: Es gibt keinen Fall, der nicht ohne goto für
>> die Nachwelt besser verständlich und nachvollziehbar ist.
>>
>> Doch, gibt es.  Aber die willst du ja gar nicht wissen.

> Bla blab bla, wo ist den der Stein der Weisen?

Lies beispielsweise "Programmieren in C", Kernighan/Ritchie, 2. Ausgabe, 
Kapitel 3.8 goto und Marken

Dort findet sich ein Beispiel was auch hier illustriert ist

http://openbook.galileocomputing.de/c_von_a_bis_z/008_c_kontrollstrukturen_012.htm#mj42701038b17e1c01b0daef016a195d43

Deine Argumentationslinie ist, du versuchst ein Dogma aufzustellen 
(niemals, nicht goto !!), während andere im Regelfall goto für abwegig 
erklären, weil mans nicht braucht, aber dennoch die Ausnahme zulassen 
bzw. anerkennen.

von Visualdingens (Gast)


Lesenswert?

Takao K. (takao_k) schrieb:

> Vielleicht siehst du es ein dass der Compiler aus dem C Source ein
> Assembler programm erzeugt, und dass ist voll mit GOTOs.

Diese Argumentation ist natürlich auch etwas fragwürdig, weil du damit 
gewissermaßen das Compilat dem Quellcode gleichstellst, nach dem Motto, 
im Endeffekt ist alles Assemblercode (oder Maschinencode). Das hieße 
dann aber auch, man könnte sich die ganze OOP mit dem ganzen 
"Klassengedöns" schenken, weil am Ende wird eh alles in einfachste 
Assembleranweisungen aufgelöst und von den Klassen bleibt nichts übrig.

;-)

von Takao K. (takao_k) Benutzerseite


Lesenswert?

Visualdingens schrieb:
> Takao K. (takao_k) schrieb:
>
>> Vielleicht siehst du es ein dass der Compiler aus dem C Source ein
>> Assembler programm erzeugt, und dass ist voll mit GOTOs.
>
> Diese Argumentation ist natürlich auch etwas fragwürdig, weil du damit
> gewissermaßen das Compilat dem Quellcode gleichstellst, nach dem Motto,
> im Endeffekt ist alles Assemblercode (oder Maschinencode). Das hieße
> dann aber auch, man könnte sich die ganze OOP mit dem ganzen
> "Klassengedöns" schenken, weil am Ende wird eh alles in einfachste
> Assembleranweisungen aufgelöst und von den Klassen bleibt nichts übrig.
>
> ;-)

Wieso denn? Es ist auch in Assembler moeglich, OOP zu verwenden, wurde 
sogar mal gemacht.

C ist schon mit Assembler zu vergleichen, der Vorteil ist halt weniger 
Schreibarbeit, und es ist nicht von Befehlssatz abhaengig.

Wenn ich einen Pointer dereferenziere, und einen Index hinzufuege, und 
dann noch inkrementiere, errinert dies schon sehr an bestimmte Assembler 
Addressierungsarten.



In BASIC gehts dies nicht ausser man arbeitet mit einem Array und es ist 
dann sehr umstaendlich.

In PASCAL geht es irgenwie so ein bisschen aber es ist ein Krampf (typ 
cast nach Integer, inkrementieren, typ cast nach pointer).

In C wird Pointer Arithmetik halt direkt unterstuetzt, es ist ein 
Merkmal dieser Sprache.

Modernes C++ arbeitet nicht mehr soviel mit Pointer Arithmetik. Hier 
werden (z.B. unter Windows) oft spezielle Spracherweiterungen verwendet 
(z.B. gibt es Array Lists, und den new operator). Da Windows aber so 
stark verbreitet ist, quasi ist es ein Standard.

Ein modernes Windows programm laesst sich nict mehr gut mit Assembler 
vergleichen- teilweise wird es sogar zuerst in MSIL uebersetzt. Also 
nicht mehr vom Befehlssatz abhaengig.

GOTO- Ich wuerde sagen +- 50 Zeilen ist in Ordnung. Viel laenger als 
einige Seiten sollte eine Funktion ohnehin nicht sein.

Aus einer Funktion herausspringen ist nicht so gut, wegen des Stacks, 
wenn es ueberhaupt geht.

In 95% aller Faelle wenn GOTO verwendet wird sind es vielleicht 10 
Zeilen, und es kann die Lesbarkeit in bestimmten Faellen erhoehen.

Insbesondere fuer Fehlerabfrage ist es einfach praktisch, nicht break zu 
verwenden, und dann eine Unmenge von Flags zu verwalten, sondern GOTO zu 
verwenden.

In Windows C++ gibt es aber schon catch/try...

Also wer ueber GOTO lamentiert dass es total schlimm ist es auch nur ein 
paar mal zu verwenden, dass ist halt kein richtiger Programmierer.

Ich verwende GOTO so oft wie moeglich, immer dann wenn es Sinn macht, 
und gut oder "besser" aussieht.

Warum denn eine Schleife verkrampfen, rueckwaerts laufen lassen und 
komplizierte tests einbauen, wenn es mit 2 GOTOs viel einfacher geht?

z.B. denk mal ueber den Fall, wenn du Daten hast in einer Struktur, 
allerdings brauchen diese nicht alle 8 bits, also verwendest du im 1. 
Feld noch die 3 oberen bits fuer etwas anderes.

Warum denn eine komplizierte Strukturdefinition, und umstaendliche 
Konstrukte? Der Sonderfall wird halt einfach einmal direkt abgefragt.

OOP mag es hingegen nicht so sehr, weitgehend nur char* zu verwenden.
Also auch wenn es eigentlich keine 8 bit chars sind, wird trotzdem ein 
char* pointer verwendet. Wozu dieser Datentyp Krampf wie in PASCAL, wenn 
es nicht wirklich zu irgendetwas nuetze ist, ausser um sicherzustellen, 
der Lehrer hat  Recht, und der Student nicht.


Warum also ist goto so verpönt? Aus Performance-Gründen! Durch goto wird 
der normale Ablauf des Programms einfach unterbrochen.

http://openbook.galileocomputing.de/c_von_a_bis_z/008_c_kontrollstrukturen_012.htm

Ist ja totaler Unsinn, das GOTO wird verwendet, weil der Progrmmablauf 
in einer bestimmten Art und Weise unterbrochen werden soll.

Das ist einfach nur total falsch.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Jörg Wunsch schrieb:
> Michael Reinelt schrieb:
>> Und, stell dir vor, ich hab mein ganzes Leben lang (leider) nie FORTRAN
>> programmiert
>
> Hast du nichts verpasst. :-)

Doch - ich könnte in FORTRAN-Diskussionen besser mitreden ;-)

von Dr. Sommer (Gast)


Lesenswert?

Takao K. schrieb:
> Hier
> werden (z.B. unter Windows) oft spezielle Spracherweiterungen verwendet
> (z.B. gibt es Array Lists, und den new operator). Da Windows aber so
> stark verbreitet ist, quasi ist es ein Standard.

Takao K. schrieb:
> In Windows C++ gibt es aber schon catch/try...
Wat? Alle diese Dinge sind im C++ Standard definiert und funktionierem 
damit in allen konformen Implementationen, wie zB GCC unter Linux - da 
ist überhaupt nix windows-spezifisch dran...

von Takao K. (takao_k) Benutzerseite


Lesenswert?

Dr. Sommer schrieb:
> Takao K. schrieb:
>> Hier
>> werden (z.B. unter Windows) oft spezielle Spracherweiterungen verwendet
>> (z.B. gibt es Array Lists, und den new operator). Da Windows aber so
>> stark verbreitet ist, quasi ist es ein Standard.
>
> Takao K. schrieb:
>> In Windows C++ gibt es aber schon catch/try...
> Wat? Alle diese Dinge sind im C++ Standard definiert und funktionierem
> damit in allen konformen Implementationen, wie zB GCC unter Linux - da
> ist überhaupt nix windows-spezifisch dran...

Gibts da auch schon Array Lists?

Ich habe nicht behauptet das catch/try Windows spezifisch ist, eher so 
zu verstehen dass es catch/try in C nicht gibt.

von anti c (Gast)


Lesenswert?

Takao K. schrieb:
> also mit deinem Sprachgebrauch hast du wohl mal ein Beratungsgespraech
> noetig.

Wenn 's fachlich nicht reicht werden wir persönlich?

Das kann ich auch:
Was bist du überhaupt für ein hässlicher Kasper? Deine Beiträge in 
verschiedenen Threads deuten auf einen Azubi im ersten Jahr. Und dann 
hier so 'ne dicke Hose? Weiss noch nicht mal wie man 'nen PAL anpackt, 
aber hier rumunken!

Das goto habe ich mit Basic unter CP/M abgelegt. Weil man es nicht 
braucht, weil es nur verwirrt.

Und du Takao hast mit Sicherheit noch nie eine Prolemstellung gehabt, 
die ein goto erfodern könnte.

von Visualdingens (Gast)


Lesenswert?

Takao K. (takao_k) schrieb:

> Warum also ist goto so verpönt? Aus Performance-Gründen! Durch goto wird
> der normale Ablauf des Programms einfach unterbrochen.

> http://openbook.galileocomputing.de/c_von_a_bis_z/...

> Ist ja totaler Unsinn, das GOTO wird verwendet, weil der Progrmmablauf
> in einer bestimmten Art und Weise unterbrochen werden soll.

> Das ist einfach nur total falsch.

Du hast dich hier auf einen Nebensatz des Autors eingschossen, den du im 
übrigen nicht mal als Zitat wiedergegeben hast. Die Schlussfolgerung des 
Autors finde ich auch missglückt und unzutreffend. Aber das Beispiel um 
das es ging ist genau das Beispiel aus dem Kernighan/Ritchie. Der Autor 
hat im übrigen klar herausgestellt, dass ein goto in C für ihn im 
Regelfall wohl keinen guten Programmierstil darstellt.

Wenn du dem Autor Ungenauigkeit vorwirfst, nun die hast du auch. Dein 
Satz hier

> Vielleicht siehst du es ein dass der Compiler aus dem C Source ein
> Assembler programm erzeugt, und dass ist voll mit GOTOs.

ist jedenfalls kein Argument für ein goto. Stell dir vor, du hast eine 
Programmiersprache in der es kein goto gibt. Dennoch wird das Compilat 
immer auch Sprungbefehle ("goto"'s) aufweisen. Ganz einfach, weil 
Prozessoren nun mal ohne Sprungbefehle nicht auskommen bzw. es im 
Regelfall keine Prozessoren ohne Sprungbefehle gibt. Oder stell dir vor, 
das goto wird in einer Neudefinition von C mal abgeschafft (nicht zu 
erwarten). Dann sticht dein Argument auch nicht mehr.

Oder das Beispiel auf das dich Dr. Sommer (Gast) hingewiesen hat 
(catch/try). Auch da warst du reichlich ungenau.

Aber es ist müßig sich am goto abzuarbeiten. Wer es nutzen möchte soll 
es tun und wer nicht, wird seine Gründe dafür haben.

von Dr. Sommer (Gast)


Lesenswert?

Takao K. schrieb:
> Gibts da auch schon Array Lists?
Kommt drauf an was du damit meinst. Array List ist irgendwie ein 
Widerspruch in sich - was denn jetzt, Array oder Liste? Es gibt 
std::vector - quasi ein intelligentes Array, std::list - eine doppelt 
verkettete Liste, std::deque - eine Doppel-Queue die als blockweise 
verkettete Liste implementiert werden kann.
Und was heißt hier "schon", Windows/Microsoft ist jetzt nicht gerade 
ganz vorne bei der C++ Entwicklung. GCC und Clang sind da weiter...

von anti c (Gast)


Lesenswert?

Takao K. schrieb:
> Viel laenger als
> einige Seiten sollte eine Funktion ohnehin nicht sein.
Hier wird nicht über den 25 Zeilen Textmodus geschrieben.

Takao K. schrieb:
> Aus einer Funktion herausspringen ist nicht so gut, wegen des Stacks,
> wenn es ueberhaupt geht.
Er weiss, wie goto funktioniert???

Takao K. schrieb:
> Ich verwende GOTO so oft wie moeglich, immer dann wenn es Sinn macht,
> und gut oder "besser" aussieht.
1. Lehrjahr und nicht E-Technik, oder er nutzt ROM-Basic. ;-)

Takao K. schrieb:
> Warum denn eine Schleife verkrampfen, rueckwaerts laufen lassen
Jetzt aber so richtig ... :-(((

von Rolf Magnus (Gast)


Lesenswert?

anti c schrieb:
> Ich spreche aus Erfahrung.
>
> Und wie schon geschrieben: Es gibt keinen Fall, der nicht ohne goto für
> die Nachwelt besser verständlich und nachvollziehbar ist.
>
> Natürlich kann man mit einem goto aus einer for Schleife springen. Das
> ist einfach und überschaubar. Aber das geht mit einem break genauso gut.

Es sei denn, es ist mehr als eine Schleifen-Ebene.
Was sieht für dich eleganter aus?
1
    int x, y;
2
3
    for (y = 0; y < size_y; ++y)
4
    {
5
        for (x = 0; x < size_x; ++x)
6
        {
7
            if (data[y][x].value == val;
8
                goto found;
9
        }
10
    }
11
found:
12
    // do something
oder
1
    int x, y;
2
3
    bool found = false;
4
    for (y = 0; y < size_y; ++y)
5
    {
6
        for (x = 0; x < size_x; ++x)
7
        {
8
           if (data[y][x].value == val;
9
           {
10
                found = true;
11
                break;
12
            }
13
        }
14
        if (found)
15
            break;
16
    }
17
    // do something

Ich finde das ohne diese umständliche Hilfsvariable besser lesbar.

> Goto ist mächtig und erlaubt Sprünge quer durchs Programm. Das ist
> gefährlich und bei einer vernünftigen Programmstruktur völlig unnötig.

Ein Messer erlaubt es, Menschen zu erstechen. Das ist auch gefährlich. 
Dennoch sind Messer sehr nützlich, wenn man sie richtig verwendet.
Nur weil man mit einem Sprachkonstrukt etwas schlechtes machen könnte, 
wird dieser dadurch nicht automatisch böse und muß zwingend vermieden 
werden.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rolf Magnus schrieb:
> Ich finde das ohne diese umständliche Hilfsvariable besser lesbar.

Das sind auch ungefähr so die Sachen, die Knuth in seinem Aufsatz
damals angebracht hat.

von Takao K. (takao_k) Benutzerseite


Lesenswert?

anti c schrieb:
> Takao K. schrieb:
>> Viel laenger als
>> einige Seiten sollte eine Funktion ohnehin nicht sein.
> Hier wird nicht über den 25 Zeilen Textmodus geschrieben.
>

Sondern 26 Zeilen.

> Takao K. schrieb:
>> Aus einer Funktion herausspringen ist nicht so gut, wegen des Stacks,
>> wenn es ueberhaupt geht.
> Er weiss, wie goto funktioniert???
>

Nicht so richtig aber es wird immer besser.

> Takao K. schrieb:
>> Ich verwende GOTO so oft wie moeglich, immer dann wenn es Sinn macht,
>> und gut oder "besser" aussieht.
> 1. Lehrjahr und nicht E-Technik, oder er nutzt ROM-Basic. ;-)
>

Klempnerlehre geschmissen.

> Takao K. schrieb:
>> Warum denn eine Schleife verkrampfen, rueckwaerts laufen lassen
> Jetzt aber so richtig ... :-(((

Warum eigentlich Schleife? Das sollte GOTO Konstrukt heissen.

von Takao K. (takao_k) Benutzerseite


Lesenswert?

> Ein Messer erlaubt es, Menschen zu erstechen. Das ist auch gefährlich.
> Dennoch sind Messer sehr nützlich, wenn man sie richtig verwendet.
> Nur weil man mit einem Sprachkonstrukt etwas schlechtes machen könnte,
> wird dieser dadurch nicht automatisch böse und muß zwingend vermieden
> werden.

Als Assemblerprogrammier weisst Du dass es verschachtelte Index garnicht 
wirklich gibt:

i=0;

rl:;if(data[i++]!=value)if(i<[xs*ys])goto rl;

Behaupte ich nicht dass es guter Programmierstil ist aber aus FOR wird 
am Ende halt immer GOTO.

Halt am Ende noch ein Dummy Element einbauen oder es muss nochmal 
getestet werden.

von Oliver S. (oliverso)


Lesenswert?

Rolf Magnus schrieb:
> Was sieht für dich eleganter aus?
1
  bool found = false;
2
  int y=0;
3
  int x=0;  
4
  while ((!found) && (y++ < size_y))
5
    while ((!found) && (x++ < size_x))
6
      if (data[y][x].value == val)
7
        found = true;

Oliver

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Oliver S. schrieb:
> Rolf Magnus schrieb:
>> Was sieht für dich eleganter aus?
>
>
1
>   bool found = false;
2
>   int y=0;
3
>   int x=0;
4
>   while ((!found) && (y++ < size_y))
5
>     while ((!found) && (x++ < size_x))
6
>       if (data[y][x].value == val)
7
>         found = true;
8
>
>
> Oliver

Für mich sieht es falsch aus :-)

(increment in der while-Bedingung wird zu früh ausgeführt, du kommst nie 
mit x=0 oder y=0 in die Schleife)

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Ich hätte aber auch noch Anwendungen, die von GOTO profitieren:

Du hast in einer Funktion viele Prüfungen und Rücksprungpunkte. So in 
der Art:
1
a=hole_a()
2
if (a==NULL) return NULL;
3
b=hole_b();
4
if (b==NULL) return NULL;
5
c=hole_c();
6
if (c==NULL) return NULL;
7
d=bereite_vor(a,b,c);
8
if (d==NULL) return NULL;
9
result = tu_was(a,b,c,d);
10
return result;

Das ist die klassische Variante eines "getarnten goto"

Problem: wenn a,b,c allokierte Ressourcen sind, muss man die wieder 
freigeben. Damit fällt das "einfache" return schon mal aus.

Man kann jetzt natürlich vor jedem return die bisher allokierten 
Ressourcen freigeben. Unschön, weil ich das mehrmals machen muss.

natürlich kann man jetzt beliebig tiefe if's verschachteln:
1
result=NULL;
2
a=hole_a()
3
if (a) {
4
   b=hole_b();
5
   if (b) {
6
      c=hole_c();
7
      if (c) {
8
         d=bereite_vor(a,b,c);
9
         if (d) {
10
            result = tu_was(a,b,c,d);
11
         }
12
      }
13
   }
14
}
15
if (d) deallocate(d);
16
if (c) deallocate(c);
17
if (b) deallocate(b);
18
if (a) deallocate(a);
19
return result;

Das wird aber schnell extrem unübersichtlich. ich bevorzuge hier 
durchaus die goto-Variante:
1
result=NULL;
2
a=hole_a()
3
if (a==NULL) goto out;
4
b=hole_b();
5
if (b==NULL) goto out;
6
c=hole_c();
7
if (c==NULL) goto out;
8
d=bereite_vor(a,b,c);
9
if (d==NULL) goto out;
10
result = tu_was(a,b,c,d);
11
out:
12
if (d) deallocate(d);
13
if (c) deallocate(c);
14
if (b) deallocate(b);
15
if (a) deallocate(a);
16
return result;

(nicht ganz korrekt, soll aber nur das Prinzip andeuten)

: Bearbeitet durch User
von Dr. Sommer (Gast)


Lesenswert?

Michael Reinelt schrieb:
> Das wird aber schnell extrem unübersichtlich

Daher wurde C++ erfunden, und eines seiner wichtigstes Features: 
Destruktoren.
1
a = hole_a (); if (!a) return;
2
b = hole_b (); if (!b) return;
3
c = hole_c (); if (!c) return;
4
return tu_was (a, b, c);

Kurz, elegant, effizient und goto-frei... Wenn man dann noch exceptions 
verwendet, kann man sich die 3 if's sparen.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Dr. Sommer schrieb:
> Daher wurde C++ erfunden, und eines seiner wichtigstes Features:
> Destruktoren.

Korrekt. Aber gehen wir mal davon aus dass wir entweder keine 
Destruktoren haben (C ohne ++) oder der Job nach dem "Out:" sich nciht 
über Destruktoren abwickeln lässt...

> Wenn man dann noch exceptions verwendet, kann man sich die 3 if's sparen.
Wobei eine Exception auch nur wieder ein getarntes goto ist ;-)

Nebenbei: Exceptions werden meiner meinung nach auch viel zu inflationär 
verwendet. ich habe zu viel Code gesehen, wo man vor lauter try/catch 
dem code nicht mehr folgen kann...

von Oliver S. (oliverso)


Lesenswert?

Michael Reinelt schrieb:
> Für mich sieht es falsch aus :-)

Das kann durchaus sein, das war nur so "dahingerotzt"...

> (increment in der while-Bedingung wird zu früh ausgeführt, du kommst nie
> mit x=0 oder y=0 in die Schleife)

Das allerdings kann nicht sein...

Oliver

von Dr. Sommer (Gast)


Lesenswert?

Michael Reinelt schrieb:
> Dr. Sommer schrieb:
>> Daher wurde C++ erfunden, und eines seiner wichtigstes Features:
>> Destruktoren.
>
> Korrekt. Aber gehen wir mal davon aus dass wir entweder keine
> Destruktoren haben (C ohne ++)
Einfach mit "g++" statt "gcc" kompilieren, dann hat man sie ;-)
> oder der Job nach dem "Out:" sich nciht
> über Destruktoren abwickeln lässt...
Wie kann das denn? Destruktoren können beliebigen Code enthalten.
>> Wenn man dann noch exceptions verwendet, kann man sich die 3 if's sparen.
> Wobei eine Exception auch nur wieder ein getarntes goto ist ;-)
So wie if, while, for, Funktionsaufrufe...
> Nebenbei: Exceptions werden meiner meinung nach auch viel zu inflationär
> verwendet. ich habe zu viel Code gesehen, wo man vor lauter try/catch
> dem code nicht mehr folgen kann...
Dann hat der Autor dieses Codes Exceptions nicht verstanden. Guter 
Exception-sicherer Code enthält nur sehr wenige try/catch-Blöcke und 
regelt das Aufräumen jeweils über... Destruktoren. In Java z.B. geht das 
natürlich nicht weswegen man sich dort mit try/catch behfelfen muss - 
einer der Gründe, warum C++ besser als Java ist.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dr. Sommer schrieb:

> Kurz, elegant, effizient und goto-frei...

Premature return ist doch nur ein verkapptes GOTO, und nach der
„reinen Lehre“ ebenfalls nicht zulässig. ;-)

: Bearbeitet durch Moderator
von Dr. Sommer (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Premature return ist doch nur ein verkapptes GOTO, und nach der
> „reinen Lehre“ ebenfalls nicht zulässig. ;-)
Deswegen ja Exceptions :-P Die hab ich im Original-Code zwecks 
Verständlichkeit zunächst ausgeblendet...

von Oliver S. (oliverso)


Lesenswert?

Dr. Sommer schrieb:
> Deswegen ja Exceptions :-P

Na ja, für sowas hier:
1
void foo(bar *p)
2
{
3
   if (p == NULL)
4
     return;
5
6
   // .. ganz viel weiterer Code
7
}

muß man jetzt keine Exception auspacken, wenn NULL dort kein 
fehlerhafter Wert des pointer ist, und es auch nichts per Destruktor 
aufzuräumen gibt.

Oliver

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Oliver S. schrieb:
>> (increment in der while-Bedingung wird zu früh ausgeführt, du kommst nie
>> mit x=0 oder y=0 in die Schleife)
>
> Das allerdings kann nicht sein...

Denke ich schon:
1
    int x;
2
    while (x++ < 10) {
3
  printf ("x=%d\n", x);
4
    }
zählt von 1 bis 10 (und nicht von 0 bis 9)

von Dr. Sommer (Gast)


Lesenswert?

Oliver S. schrieb:
> muß man jetzt keine Exception auspacken, wenn NULL dort kein
> fehlerhafter Wert des pointer ist, und es auch nichts per Destruktor
> aufzuräumen gibt.
ICH habe ja nichts gegen ein einfaches return gesagt ;-)

von Takao K. (takao_k) Benutzerseite


Lesenswert?

Michael Reinelt schrieb:
> Oliver S. schrieb:
>>> (increment in der while-Bedingung wird zu früh ausgeführt, du kommst nie
>>> mit x=0 oder y=0 in die Schleife)
>>
>> Das allerdings kann nicht sein...
>
> Denke ich schon:
>
1
>     int x;
2
>     while (x++ < 10) {
3
>   printf ("x=%d\n", x);
4
>     }
5
>
> zählt von 1 bis 10 (und nicht von 0 bis 9)
1
int x=-1;
2
while(++x<10)printf("x=%d\n",x);

sowas geht halt in BASIC oder PASCAL nicht.
Am besten noch so ein paar x und i global bereithalten.

Das sollte dann aber nur in kleineren Embedd C Programmen gemacht 
werden.
Also nicht etwa dass ich es wirklich anrate.

vielleicht gehts ja garnicht richtig, nicht ausgetestet...

von Yalu X. (yalu) (Moderator)


Lesenswert?

Michael Reinelt schrieb:
> Wobei eine Exception auch nur wieder ein getarntes goto ist ;-)

Viel schlimmer noch: Das sind getarnte Longjumps. Und die sind an
Bösartigkeit wohl kaum noch zu übertreffen.

SCNR ;-)

von Rolf Magnus (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Jörg Wunsch schrieb:
>> Premature return ist doch nur ein verkapptes GOTO, und nach der
>> „reinen Lehre“ ebenfalls nicht zulässig. ;-)
> Deswegen ja Exceptions :-P

Das ist auch nur ein besser verstecktes "premature return". Die Idee 
dieser "Lehre" ist ja, nur genau einen einzigen Punkt zu haben, an dem 
die Funktion verlassen wird, nämlich am Ende. Das ist mit Exceptions 
auch nicht gegeben, es sei denn, ich fange in jeder Funktion alle 
Exceptions ab.

Yalu X. schrieb:
> Michael Reinelt schrieb:
>> Wobei eine Exception auch nur wieder ein getarntes goto ist ;-)
>
> Viel schlimmer noch: Das sind getarnte Longjumps. Und die sind an
> Bösartigkeit wohl kaum noch zu übertreffen.

Früher waren beim GCC die Exceptions ja sogar über Longjump 
implementiert. Heute wird das aber meines Wissens anders gehandhabt.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rolf Magnus schrieb:
> Heute wird das aber meines Wissens anders gehandhabt.

Die longjmp-Implementierung ist glaub' ich nach wie vor als Fallback
möglich, falls eine bestimmte Architektur nichts besseres zu bieten
hat.  Die hat irgendwas mit "sjlj" im Namen, für "setjump/longjmp".

von Dr. Sommer (Gast)


Lesenswert?

Yalu X. schrieb:
> Viel schlimmer noch: Das sind getarnte Longjumps. Und die sind an
> Bösartigkeit wohl kaum noch zu übertreffen.
Jo, aber Exceptions können nur aus Funktionen *raus*springen - am Stack 
nach oben - und rufen auch "sauber" Destruktoren auf. Daher würde ich 
sie als weit weniger bösartig als longjmp sehen, und auch sauberer als 
manuelle (fehleranfällige) Fehlerbehandlung & Aufräumen. Wenn man 
partout nur einen Exit-Punkt in einer Funktion haben will wird man wohl 
zwangsläufig ziemlichen Spaghetticode (endlose if-else-Ketten) 
produzieren?!

von Rolf Magnus (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Wenn man partout nur einen Exit-Punkt in einer Funktion haben will wird
> man wohl zwangsläufig ziemlichen Spaghetticode (endlose if-else-Ketten)
> produzieren?!

Es sei denn, man benutzt goto ;-)

von Dr. Sommer (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Es sei denn, man benutzt goto ;-)
Mit goto aus Schleifen und if's rauszuspringen um dann einen einzigen 
Exit-Punkt in der Funktion zu haben ist irgendwie... inkonsequent? 
Widersinnig? Bescheuert? :-D

von Takao K. (takao_k) Benutzerseite


Lesenswert?

Rolf Magnus schrieb:
> Dr. Sommer schrieb:
>> Wenn man partout nur einen Exit-Punkt in einer Funktion haben will wird
>> man wohl zwangsläufig ziemlichen Spaghetticode (endlose if-else-Ketten)
>> produzieren?!
>
> Es sei denn, man benutzt goto ;-)

Oder garkeine Fehlerbehandlung, muss halt der Reset Taster gedrueckt 
werden, oder das FAT FFS ist kaputt... Lesen geht ja noch, aber wenn 
Dateien geschrieben werden, sollte am besten die Versorgungsspannung 
ueberwacht werden, und alle Fehler genau ausgetestet werden.

Muesste halt ganz konkret gegenueber gestellt werden wie es mit, und 
ohne GOTOs aussieht (Ich gehe jetzt mal von embedded C aus).

Unter Windows kann man sich auch nicht total darauf verlassen dass eine 
Allokierung von irgenetwas auch geklappt hat, koennte ja sein, der 
Speicher ist knapp, oder ein Skrip laeuft gerade Irre.

Genaugenommen muss es immer ausgetestet werden, und im Fehlerfall muss 
zu einem sinnvollen Punkt zurueckgefunden werden. Hier auch nie darauf 
verlassen das ein Requester ueberhaupt geoeffnet werden kann.

Nach einigen Wochen ohne Reboot ist das System manchmal sosehr 
zerschossen, dass es nicht mehr ohne reboot geht.

GOTO oder nicht ist da eher noch eine Nebensache, mal davon abgesehen ob 
eine Fehlerbehandlung ueberhaupt durchgehend eingebaut wird, oder es 
halt bestenfalls einen Requester mit einer krausen Message gibt, und 
RETRY CANCEL ABORT.

Unter Windows sind Programme oft uebervorsichtig, es wird dann 
abgebrochen, unter LINUX gibts jede Menge Fehlermeldungen in der 
Konsole, macht aber nicht wirklich etwas, und dass Programm kann 
trotzdem noch weitgehend genutzt werden.

Wenn es mehrere Threads gibt kann ohnehin nicht einfach so hin und 
hergesprungen werden. Solche Software wird dann oft garnicht mehr mit 
klassischen verschachtelten Schleifen, if und case Kontrukten aufgebaut, 
sondern diese ist dann weitgehend mit Skripts realisiert. Diese koennen 
an C angelehnt sein, es kann binaercode in Tabellen sein, oder eine 
spezialisierte Skriptsprache mit richtigem Parser.

MPLABX verwendet z.B. nicht mehr soviel Windows, sondern Java, und 
vielzaehlige Module. Wenn z.B. der Debugger spinnt, geht die IDE 
trotzdem noch.

Unbedingt mal "Writing Secure Software" von Microsoft lesen.

von Marc P. (marcvonwindscooting)


Lesenswert?

Dr. Sommer schrieb:
> Rolf Magnus schrieb:
>> Es sei denn, man benutzt goto ;-)
> Mit goto aus Schleifen und if's rauszuspringen um dann einen einzigen
> Exit-Punkt in der Funktion zu haben ist irgendwie... inkonsequent?
> Widersinnig? Bescheuert? :-D

Okay, noch ein Vorschlag:
1
const int A = initA();
2
if (A==0) goto doneA;
3
// Arbeit hier
4
5
const int B = initB(A);
6
if (B==0) goto doneB;
7
8
// Hauptarbeit hier
9
10
doneB: cleanUpB();
11
doneA: cleanUpA();
12
return ..

Wie geht das sch"oner mit Exceptions / Destruktoren?? Ich hab sowas in 
einem realen Programm drin ('mxli'), es geht hier nicht um graue 
Theorie, sondern um stufenweise Initialisierung und eben auch passende 
Aufraeumarbeiten im Fehlerfall.

: Bearbeitet durch User
von Dr. Sommer (Gast)


Lesenswert?

Takao K. schrieb:
DAS ist halt der Vorteil von Exceptions - man kann seinen Code einfach 
so schreiben als träten nie Fehler auf, und wenn doch stürzt das 
Programm wenigstens "sauber" ab anstelle von irgendeinen potentiell 
gefährlichen Unsinn zu machen...

Marc P. schrieb:
> Wie geht das sch"oner mit Exceptions / Destruktoren?
So: http://ideone.com/3lNflM
Man programmiert sich EIN mal eine Klasse pro Resourcen-Typ inklusive 
Destruktor zum Aufräumen, initialisiert im Konstruktor und wirft evtl. 
eine Exception, und muss dann wie in tuwas() gezeigt einfach nur noch 
Instanzen davon anlegen. Dort braucht man dann überhaupt keine explizite 
Fehlerbehandlung mehr (kein goto, kein if) und kann so programmieren als 
könnte nichts schief gehen. Sowohl Im Fehler (Exception) -Fall als auch 
im Erfolgs-Fall wird dann ordentlich genau das aufgeräumt was aufgeräumt 
werden muss.
Hier haben wir natürlich ein gewisses Missverhältnis zwischen 
"Hilfs-Code" (die Klassen) und dem eigentlichen Algorithmus ("tuwas"), 
aber typischerweise implementiert man sich einmal so eine Klasse (wie zB 
std::ifstream für eine Datei) und verwendet sie dann in vielen großen 
Algorithmen, die dadurch viel kürzer und einfacher werden.

von Dr. Sommer (Gast)


Lesenswert?

PS.: Und mit den so definierten Klassen kann man dann viele Funktionen 
im "tuwas"-Stil schreiben und erhält saubere Fehlerbehandlung mit nur 
einem einzigen try-catch-Block im Programm - dank Destruktoren.

von Rolf Magnus (Gast)


Lesenswert?

Dr. Sommer schrieb:
> DAS ist halt der Vorteil von Exceptions

Nicht von Exceptions, sondern von RAII. Wenn ich zwischendrin ein return 
machen würde (oder ein goto) statt eine Exception zu werfen, würde das 
genauso funktionierten.
Auf der anderen Seite funktiniert es aber nicht in Sprachen, die zwar 
Exceptions, aber keine vernünftigen Destruktoren haben, da im 
Exception-Fall die Ressourcen eben nicht unbedingt automatisch 
aufgeräumt werden. Lustigerweise fehlen (deterministische) Destruktoren 
in einigen Sprachen gerade deshalb, weil sie einen Garbage Collector 
haben, der ja eigentlich für das automatische Aufräumen da ist. Dies ist 
aber leider inkonsequent umgesetzt, da ausschließlich Speicher und keine 
anderen Ressourcen behandelt werden. Um die muß man sich dann wieder von 
Hand kümmern.

von Dr. Sommer (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Nicht von Exceptions, sondern von RAII.
Ohne Exceptions hätte man aber im o.g. Fall (= wenn man Fehler nicht 
explizit behandelt) ein Problem. Also wenn schon dank RAII+Exceptions.

von Kaj (Gast)


Lesenswert?

Michael Reinelt schrieb:
> Denke ich schon:
>  int x;
>  while (x++ < 10) {
>    printf ("x=%d\n", x);
>  }
> zählt von 1 bis 10 (und nicht von 0 bis 9)
Noe. x hat irgendeinen Wert, da x nicht initialisiert wurde. Damit 
laeuft die schleife im schlechtesten falle endlos, wenn x zu beginn der 
schleife >=10 (weil nicht initialisiert) ist und x nach dem overflow 
wieder einen Wert bekommt der >= 10 ist. Das koennte passieren, da das 
verhalten bei einem signed overflow ja nicht definiert ist.

anti c schrieb:
> Das goto zerstört
> den Programmfluss und macht die Software unübersichtlich. Im
> Profibereich also ein no go.
Schon mal in einen Kernel(z.B. Linux) oder in Treiber geschaut? Oder ist 
Kernel-/Treiberprogrammierung kein Profibereich?

von Marc P. (marcvonwindscooting)


Lesenswert?

Dr. Sommer schrieb:
> Sowohl Im Fehler (Exception) -Fall als auch
> im Erfolgs-Fall wird dann ordentlich genau das aufgeräumt was aufgeräumt
> werden muss.

Verstanden. Interessant ist die Ausgabe (zuerst 'cleanup A' dann 'B 
failed') aber natuerlich logisch.

> Hier haben wir natürlich ein gewisses Missverhältnis zwischen
> "Hilfs-Code" (die Klassen) und dem eigentlichen Algorithmus ("tuwas"),

Leider gibt es aber auch Faelle, bei denen man weiss, dass man die 
Klassen nicht wiederverwerten wird, weil das Problem zu speziell ist.
Ich verstehe meine Wahl des goto mittlerweile so: aufgrund diverser 
Kompromisse die ich im Vorfeld einging (ich bin ein grosser Fan von 
Speicher auf dem Stack, nicht auf dem Heap anzulegen; meine Variablen 
sind immer so lokal wie moeglich und werden nicht dupliziert; die 
Funktion parst die Kommandozeile, was vieles in der Reihenfolge 
laufzeit-bestimmt macht; ...) war die Wahl des goto das geringere Uebel. 
Es ist nicht das Konstrukt goto das ich so mag, sondern der Kontext, der 
das goto als einzig einfachen = (kurzen) Ausweg uebrig liess.

Der heftigste Kompromiss meines Programms ist wohl der: es ist ein 
C-Programm (ohne ++). Schade, dass ich nicht weiss, ob ich in einem 
C++-Programm ebenso gehandelt haette.

von Dr. Sommer (Gast)


Lesenswert?

Marc P. schrieb:
> Verstanden. Interessant ist die Ausgabe (zuerst 'cleanup A' dann 'B
> failed') aber natuerlich logisch.
Ja das muss natürlich so.
>
>> Hier haben wir natürlich ein gewisses Missverhältnis zwischen
>> "Hilfs-Code" (die Klassen) und dem eigentlichen Algorithmus ("tuwas"),
>
> Leider gibt es aber auch Faelle, bei denen man weiss, dass man die
> Klassen nicht wiederverwerten wird, weil das Problem zu speziell ist.
Dann kann man sich so behelfen: http://ideone.com/5qJKch
Man schreibt pro durchzuführender Aufräum-Aktion ein
1
auto irgendeinFreierBezeichner = cleanup ([&] () { /* hier aufräumaktion */ });
Die wird dann garantiert immer durchgeführt, wenn die Funktion 
zurückkehrt - unabhängig ob per "return", Erreichen des "}", oder 
Exception - allerdings nur, wenn die Ausführung zuvor eben diese Zeile 
erreicht hat (wenn die Funktion zuvor zurückgekehrt ist, nicht).
> Ich verstehe meine Wahl des goto mittlerweile so: aufgrund diverser
> Kompromisse die ich im Vorfeld einging (ich bin ein grosser Fan von
> Speicher auf dem Stack, nicht auf dem Heap anzulegen;
Sollte man immer machen, da der Stack viel schneller ist...
> meine Variablen
> sind immer so lokal wie moeglich und werden nicht dupliziert;
Auch sehr sinvoll, um klarzustellen was sie alles beeinflussen
> Der heftigste Kompromiss meines Programms ist wohl der: es ist ein
> C-Programm (ohne ++). Schade, dass ich nicht weiss, ob ich in einem
> C++-Programm ebenso gehandelt haette.
Du kannst ja wie gesagt einfach mit "g++" statt "gcc" kompilieren und 
schon hast du ein C++ Programm in dem du alle o.g. Nettigkeiten anwenden 
kannst.

von Marc P. (marcvonwindscooting)


Lesenswert?

Dr. Sommer schrieb:
> auto irgendeinFreierBezeichner = cleanup ([&] () { /* hier aufräumaktion
> */ });

Wow! Seit wann? 'Anonyme' Funktionen? Das werde ich sicher verwenden!
Danke fuer den Tip!!

von Dr. Sommer (Gast)


Lesenswert?

Marc P. schrieb:
> Wow! Seit wann? 'Anonyme' Funktionen? Das werde ich sicher verwenden!
> Danke fuer den Tip!!
Seit 2011 (C++11) - neben eine Menge anderer toller Features. Ist in der 
Tat äußerst praktisch ;-)

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.