Forum: Compiler & IDEs Rust als Embedded-Programmiersprache


von nga (Gast)


Lesenswert?

Hallo zusammen,

hat jemand von euch schon einmal Erfahrung mit der Programmiersprache 
Rust im Embedded Umfeld (primär Cortex-M) gemacht? Gerade im Vergleich 
zu C oder C++ scheint es einige Vorteile zu geben.

Ich habe mir mit C und C++ schon öfters effizient in den Fuß geschossen, 
was gerade auf µCs oft nicht direkt auffällt, das es keinen SegFault wie 
auf dem PC gibt (Bitte keine Belehrungen dazu. Ich bin mir sicher, dass 
solche Dinge jedem schon einmal passiert sind... :-) ).

Rust vermeidet anscheinend ja effektiv Dangling Ponters und es gibt auch 
keine NULL-Pointer. Array-Bounds werden auch gecheckt. Das nimmt ja 
schon mal das meiste Gefahren-Potential.

Was ich mich noch frage: was passiert standardmäßig im Falle eines 
panic!()-Aufrufs?

Wie sieht es mit der Effizienz des erzeugtem Maschienencodes aus? Es 
wird ja LLVM benutzt, was ja schon einiges erwarten lässt (clang ist mWn 
auch ein LLVM-Frontend). Ich gehe stark davon aus, dass pure C/C++ eine 
kleinere Runtime hat (und damit erst einmal ein kleineres Binary), aber 
bei größeren Projekten sieht das evtl. anders aus (kann ich mangels 
einem solchen Projekt nicht testen).

Über Antworten freue ich mich.

Grüße,
nga

: Gesperrt durch User
von Kaj (Gast)


Lesenswert?

Schau mal hier:

Rust your ARM microcontroller!
http://blog.japaric.io/quickstart/

Vielleicht ist da ja was hilfreiches bei.

nga schrieb:
> Rust vermeidet anscheinend
Nicht nur anscheinend: es tut es. Der Preis dafuer ist halt eine 
laengere Compilierzeit. Man bekommt praktisch fuer alles einen Error, wo 
es in C/C++ noch nicht mal eine Warnung gibt bzw. nur, wenn man sie 
einschaltet.

Ausserdem muss man sich an ein paar Stellen eine neue Art der 
Programmierung angewoehnen, da man z.B. nicht mehrer Zeiger mit 
Schreibzugriff haben kann (ausser in unsafe {}), und das Borrowing 
erfordert auch ein umdenken.

Ich arbeite mich gerade selber in Rust ein, allerdings erstmal auf dem 
Desktop unter Linux. Ich will es dann aber auch auf ARM und AVR nutzen.

von A. S. (Gast)


Lesenswert?

Kaj schrieb:
> wo es in C/C++ noch nicht mal eine Warnung gibt bzw. nur, wenn man sie
> einschaltet.

Ja, genau: für die allermeisten C-Probleme gibt es Warnungen, die man 
einschalten kann.... Und notfalls gibt es lint und Mists. Und Warnung 
als Error gibt's auch.

Beitrag #5513351 wurde von einem Moderator gelöscht.
von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Karl K. schrieb im Beitrag #5513351:

> Behalte Deinen C-Mist, hat keiner danach gefragt.

man man man, Turett-Syndrom, oder was? Hat er wohl nach gefragt:

wer schreibt:

> Gerade im Vergleich
> zu C oder C++ scheint es einige Vorteile zu geben.

fragt nach genau sowas.

Wobei, in so einem Fall C und C++ in einem Atemzug zu nennen, da ist 
schon klar, warum es beim programmieren zu Schüssen ins Bein kommt.

Und, mal ehrlich, wer wegen

> Array-Bounds werden auch gecheckt.

Meint eine neue Sprache lernen zu müssen ... Man könnte dann auch 
einfach (C++) gecheckte Zugriffe nehmen und fertig?

C und C++ hier in einem Atemzug zu nennen, klingt auch schon verdächtig. 
C++ und C haben eigentlich was Pointer angeht, nicht mehr viel 
gemeinsam. C++ mit Raw Pointern ist das selbe wie Rust mit Raw Pointern. 
Und null-Referenzen gibt es in C++ nicht.

Hat wirklich schonmal jemand mit -Wall und smart-Pointern Probleme mit 
dangling Pointers oder nullpointern gehabt? Das klingt für mich extrem 
exotisch.


Unabhängig davon macht Rust wirklich einen netten Eindruck und warum 
nicht, wenns Freude macht. Aber die vom TO vorgeschobenen C++ Probleme 
sind Quark.

vlg
 Timm

: Bearbeitet durch User
von Karl K. (karl2go)


Lesenswert?

Timm R. schrieb:
> Meint eine neue Sprache lernen zu müssen ... Man könnte dann auch
> einfach (C++) gecheckte Zugriffe nehmen und fertig?

Es ist schon auffällig, dass hier im Forum in so ziemlich jedem Thread 
in dem eine andere Programmiersprache erwähnt wird die C-Freaks 
aufschlagen und erklären, wie toll ihr C ist und dass man das ja auch 
mit C könnte.

Ihr nervt!

von Marian M. (mrhat2010)


Lesenswert?

Karl K. schrieb:
> Timm R. schrieb:
>> Meint eine neue Sprache lernen zu müssen ... Man könnte dann auch
>> einfach (C++) gecheckte Zugriffe nehmen und fertig?
>
> Es ist schon auffällig, dass hier im Forum in so ziemlich jedem Thread
> in dem eine andere Programmiersprache erwähnt wird die C-Freaks
> aufschlagen und erklären, wie toll ihr C ist und dass man das ja auch
> mit C könnte.
>
> Ihr nervt!

Timm sprach aber von C++ nicht von C

von völlig egal (Gast)


Lesenswert?

Marian M. schrieb:
>> Es ist schon auffällig, dass hier im Forum in so ziemlich jedem Thread
>> in dem eine andere Programmiersprache erwähnt wird die C-Freaks
>> aufschlagen und erklären, wie toll ihr C ist und dass man das ja auch
>> mit C könnte.
>>
>> Ihr nervt!
>
> Timm sprach aber von C++ nicht von C

Nur mal so nebenbei als kleiner Seitenhieb: Egal ob er von C oder C++ 
sprach, war DAS nicht genau das, was einigen von euch immer so an Moby 
aufgestoßen ist, wenn er sein Assembler unerwartet in den Ring warf? Und 
warum stört euch der gleiche Vorgang plötzlich viel weniger oder gar 
nicht, wenn anstatt mit Assembler nun mit C oder C++ in eine 
Rust-Diskussion hineingegrätscht wird?

Kann es sein, dass hier gewisse verbreitete C, C++ Vorlieben zu einer 
deutlich höheren Toleranzschwelle gegenüber Störenfrieden führen?

Pharisäertum hier?

von Marian M. (mrhat2010)


Lesenswert?

völlig egal schrieb:
> Marian M. schrieb:
>>> Es ist schon auffällig, dass hier im Forum in so ziemlich jedem Thread
>>> in dem eine andere Programmiersprache erwähnt wird die C-Freaks
>>> aufschlagen und erklären, wie toll ihr C ist und dass man das ja auch
>>> mit C könnte.
>>>
>>> Ihr nervt!
>>
>> Timm sprach aber von C++ nicht von C
>
> Nur mal so nebenbei als kleiner Seitenhieb: Egal ob er von C oder C++
> sprach, war DAS nicht genau das, was einigen von euch immer so an Moby
> aufgestoßen ist, wenn er sein Assembler unerwartet in den Ring warf? Und
> warum stört euch der gleiche Vorgang plötzlich viel weniger oder gar
> nicht, wenn anstatt mit Assembler nun mit C oder C++ in eine
> Rust-Diskussion hineingegrätscht wird?
>
> Kann es sein, dass hier gewisse verbreitete C, C++ Vorlieben zu einer
> deutlich höheren Toleranzschwelle gegenüber Störenfrieden führen?
>
> Pharisäertum hier?

Ich verstehe worauf du hinaus willst, nur war es nicht meine Absicht C 
oder C++ besser als Rust darzustellen, ich hatte nur angemerkt, dass 
Timm von C++ und nicht von C gesprochen hat.

Persönlich empfinde ich es durchaus als Bereicherung eine weitere 
Sprache auf Controllern lauffähig zuhaben, nur sehe ich die 
Schwierigkeiten bei Rust darin wie bisheriger Code, welcher in C oder 
C++ geschrieben wurde, wiederverwendet werden kann. Bisher dachte ich, 
dass dazu dieser Teil des Projektes (zB eine Bibliothek) als unsafe 
eingebunden werden muss, was ja nicht der Weisheit letzter Schluss sein 
kann.

Sollte ich mich hier irren, könnten diejenigen bitte ein paar Beispiele 
verlinken, ich lerne durchaus gerne dazu ;)

Aber wenn man überlegt wie lange es gedauert hat bis sich C++ überhaupt 
in die Köpfe mancher embedded Entwickler eingeschlichen hatte, kann es 
gerade bei Rust noch Jahre dauern bis es zu einer nennenswerten 
Verbreitung kommt, aber eventuell gibt es ja dann doch ein paar 
Einflüsse die das beschleunigen könnten.

von Rustecean (Gast)


Lesenswert?

Kaj schrieb:
> Schau mal hier:
>
> Rust your ARM microcontroller!
> http://blog.japaric.io/quickstart/
>
> Vielleicht ist da ja was hilfreiches bei.

Besser hier: https://rust-embedded.github.io/discovery/

Vom selben Autor, aber neuer, und damit auf dem aktuellen Stand... Xargo 
wird z. B. nicht mehr benötigt: 
https://users.rust-lang.org/t/cortex-m-library-development-now-possible-on-beta-and-the-path-towards-stable-embedded-rust/17420

von Joe J. (j_955)


Lesenswert?

[GELÖSCHT]

Will keinen Glaubenskrieg anzetteln.;-)

: Bearbeitet durch User
von Ben W. (ben_w)


Lesenswert?

hier ist noch ein kleiner fanboy von Rust im embedded Bereich :)
denke es hat sehr großes Potential.

Timm R. schrieb:
> Meint eine neue Sprache lernen zu müssen ... Man könnte dann auch
> einfach (C++) gecheckte Zugriffe nehmen und fertig?

korrigiere mich wenn ich falsch liege aber smartpointers etc. werden zur 
Laufzeit überprüft, während Rust versucht das ganze noch zur Compilezeit 
aufzulösen, was einen minimalistischeren Code ergeben sollte.

wenn man sich die Beispiele auf japarics blog anschaut, ist der 
generierte Assembler schon wirklich sehr effizient.

Klar kann ich sowas auch mit C und C++ erreichen aber mit wesentlich 
mehr Aufwand.
Für mich ist es eine einfache Kosten Nutzen Rechnung. Ich persönlich 
kann eher Rust lernen als C und/oder C++ so gut beherrschen um das 
gleiche zu erreichen.

Auf der embedded world 2018 habe ich den ersten Stand mit 
Dienstleistungen für Rust im embedded Bereich gesehen :)

für manche sachen wird wohl noch der nightly build vom Rust compiler 
benötigt,
mit dem Rust 2018 release (erwartet im Dezember) soll embedded targets 
out of the box unterstützt werden

nga schrieb:
> Was ich mich noch frage: was passiert standardmäßig im Falle eines
> panic!()-Aufrufs?
die cortex-rt crate kümmert sich darum. Default ist (glaube ich) es wird 
ein Fehler über semihosting oder SWO ausgegeben und anschließend eine 
endlosschleife betreten. Lässt sich aber auch umleiten auf z.B. einen 
UART oder so ...

von Alex E. (tecnologic) Benutzerseite


Lesenswert?

Ben W. schrieb:
> korrigiere mich wenn ich falsch liege aber smartpointers etc. werden zur
> Laufzeit überprüft, während Rust versucht das ganze noch zur Compilezeit
> aufzulösen, was einen minimalistischeren Code ergeben sollte.

Ich kann dich korrigieren :). C++ macht das bei std::array z.B. auch zur 
Compilezeit. Im Endeffekt wird auch in den aktuellen C++ Standards 
(11,14,17,21 ... ) viel auf solche Themen eingegangen. Der Punkt ist 
aber dass man sich es auch angewöhnen muss die STL in C++ Projekten zu 
nutzen und man sich sehr mit der Toolchain beschäftigen muss, weil es 
immer mal wieder Desktop Funktionalitäten gibt die man für embedded 
deaktivieren muss. (z.B. Exceptions, RTTI ...).

Daher kann ich es schon verstehen das einige hier den Weg über eine 
andere Sprache, die verspricht einem diese Fallstricke abzunehmen, gehen 
wollen.

Deshalb weiter so!

Ich wollte nur diese Diskussion "C++ kann das nicht aber Rust" 
entkräften. Das zeigt eigentlich schon was modernes C++ falsch macht. 
Die Leute wissen einfach nicht mehr was C++ alles kann und wie die 
Ganzen neuen Konstrukte funktionieren. Deshalb ist Rust vllt. wirklich 
die einfachere Alternative.

Gruß

Alex

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Lieber Karl,

Karl K. schrieb:

> Es ist schon auffällig, dass hier im Forum in so ziemlich jedem Thread
> in dem eine andere Programmiersprache erwähnt wird die C-Freaks
> aufschlagen und erklären, wie toll ihr C ist und dass man das ja auch
> mit C könnte.

Das Problem ist vielleicht auch, dass Du, weil du so genervt bist, 
einfach nicht liest? Der Ursprungs-Post ist – auch – ein C, C++ vs. Rust 
Post. Wenn der OP das nicht will, muss er einfach die Schlüsselwörter 
weglassen.

Zumal C++ vs. besonders "ansprechend" gestaltet ist, weil der OP 
nahelegt, dass er gar kein C++ kann, was das Ganze etwas grotesk macht.

Ich bin auch kein C Freak, noch nicht mal ein C++ Freak, du wirst auch 
von mir keinen einzigen Beitrag finden können, der die von Dir 
behaupteten Eigenschaften zeigt. Programmiersprachen sind Werkzeuge und 
keine Religionen.

Das C++ für embedded eine sehr heikle Sache sein kann, weil es schwierig 
ist, den Überblick zu behalten welche Features den Code blähen, ist 
bekannt und unbestritten.

Ich habe auch nicht das geringste gegen Rust einzuwenden, warum auch? 
Ich habe schonmal angefangen Rust zu lernen, zu der Zeit war aber noch 
nicht so viel los damit, ist aber auch schon was her.

Könnte sich denn vielleicht einer der Rust-kundigen und C++-kundigen 
erbarmen, mal ein minimales Beispiel mit c++ Pointer-Katastrophe zu 
zeigen und wie es in Rust besser läuft? Das wäre doch sicher für mehrere 
Rist-Unkundige interessant und erhellend? Mir fehlt da einfach die 
Vorstellungskraft.

vlg

Timm

: Bearbeitet durch User
von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Hi Ben,

Ben W. schrieb:

> Timm R. schrieb:
>> Meint eine neue Sprache lernen zu müssen ... Man könnte dann auch
>> einfach (C++) gecheckte Zugriffe nehmen und fertig?
>
> korrigiere mich wenn ich falsch liege aber smartpointers etc. werden zur
> Laufzeit überprüft, während Rust versucht das ganze noch zur Compilezeit
> aufzulösen, was einen minimalistischeren Code ergeben sollte.

smart Pointer werden AFAIK gar nicht geprüft. Wenn ein smart Pointer 
null ist, gibts zur Laufzeit einen Knall. Sie verhindern nur böse Sachen 
wie:
1
    char* dp = NULL;
2
    {
3
        char c;
4
        dp = &c;
5
    }
6
    *dp = 42;

Was ja vermutlich so Szenarien sind, mit denen sich Anfänger in den Fuß 
schießen?

Bounds werden natürlich (ich weiße es nicht) in Rust genau so zur 
Laufzeit gecheckt, wie auch in C++. Das kann ja gar nicht anders gehen.

vlg
 Timm

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


Lesenswert?

Timm R. schrieb:
> Könnte sich denn vielleicht einer der Rust-kundigen und C++-kundigen
> erbarmen, mal ein minimales Beispiel mit c++ Pointer-Katastrophe zu
> zeigen und wie es in Rust besser läuft? Das wäre doch sicher für mehrere
> Rist-Unkundige interessant und erhellend?

Ja, das fände ich konstruktiv! Gerne auch in C. Und mit Angabe der 
Warnungen, die man dafür ausblenden muss oder nicht einschalten darf.

von Joerg W. (joergwolfram)


Lesenswert?

Für Rust benötigt man meines Wissens nach LLVM, die Auswahl an Backends 
ist dort aber noch überschaubar. Momentan setze ich (je nach 
Verfügbarkeit) auf GCC und SDCC, was wegen dem SDCC schon C++ 
ausschließt. Es gibt zwar genügend Anleitungen, um eigene Backends für 
LLVM zu schreiben, aber das ist ein Aufwand, den ich mir nicht antun 
möchte.

von rostiger Nagel (Gast)


Lesenswert?

Also ich weiß nicht, geht das hier nicht 'schöner'?:
1
// Send a single character
2
    usart1.tdr.write(|w| w.tdr().bits(u16::from(b'X')));

von Yalu X. (yalu) (Moderator)


Lesenswert?

Ich habe mich bisher nur wenig mit Rust beschäftigt, halte es aber für
eine der interessantesten Programmiersprachen aus jüngerer Zeit.

Rust verfolgt ähnliche Ziele wie C++, nämlich relativ hohe Abstraktion
mit minimalem bis gar keinem Laufzeit-Overhead.

Mein Eindruck ist, dass alle wesentlichen Features von C++ in Rust
ebenso verfügbar sind oder aber durch mindestens gleichwertige andere
Features ersetzt wurden. Da diese Features bereits frühzeitig in das
Sprachkonzept eingeflossen sind und nicht, wie in C++, über viele Jahre
verteilt, ist Rust (zumindest derzeit noch) trotz seiner Mächtigkeit
eine recht schlanke Sprache ohne Kompatibilitätsaltlasten.

Wenn ich demnächst etwas mehr Zeit habe, werde ich versuchen, meine
Rust-Kenntnisse etwas zu vertiefen und in kleineren Hobbyprojekten
anstelle von C oder C++ zu nutzen.

Timm R. schrieb:
> Könnte sich denn vielleicht einer der Rust-kundigen und C++-kundigen
> erbarmen, mal ein minimales Beispiel mit c++ Pointer-Katastrophe zu
> zeigen und wie es in Rust besser läuft?

Hier ist ein kleines Beispiel von Steve Klabnik:

  https://github.com/steveklabnik/uniq_ptr_problem

von mh (Gast)


Lesenswert?

Ich habe keine Ahnung von rust und habe daher nichts zum eigentlich 
Thema zu sagen.

Aber zu diesem Link kann ich etwas sagen.
Yalu X. schrieb:
> Hier ist ein kleines Beispiel von Steve Klabnik:
>
>   https://github.com/steveklabnik/uniq_ptr_problem

Eine ganze Seite "Seite", die mit dem Ziel:
1
While it's true that C++'s smart pointers are a huge leap forward, they aren't actually safe in all cases. I always forget what the exact cases are, so I made this page to remind myself.
erstellt wurde, enhält genau ein Beispiel und dieses eine Beispiel ist 
trivial und sollte für jeden offensichtlich sein, der verstanden hat was 
ein unique_ptr und was move-Semantik ist.

Es ist kein Beispiel für Probleme mit smart-Pointern in c++, sondern 
eher für Probleme mit der move-Semantik. Probleme die rust anscheinend 
auch hat, wie man der gleichen Seite entnehmen kann. Ok bei rust gibt 
der Compiler eine Meldung aus, die man aber auch in c++ bekommt, wenn 
man clang-tidy benutzt.

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Hallo Yalu,

ja, ich denke, das Beispiel ist gültig. Danke!

Der Claim ist ja gerade, dass Rust sich wie ein erfahrener Ratgeber 
verhält und verhindert, dass man (aus versehen) blöde Dinge tut.

Die Move Semantik ist scheinbar so eindeutig, dass der Compiler diesen 
Fehler verhindern kann, das ist ein Beleg für den Claim.

Natürlich kommt das zu einem Preis, natürlich kann man sagen, dass das 
echt ein saublöder Fehler ist, den erfahrene Programmierer nie machen 
würden, aber darum geht es ja gerade. Unfälle passieren, weil man 
unachtsam blöde Dinge tut.

Vermutlich warnt der C++ Compiler nicht, weil std::move ja nicht move 
heißt, sondern nur move versuchen und was genau passiert, weiß man 
nicht. Bei einem anderen Typ könnte das Beispielprogramm problemlos 
laufen. Andererseits ist bei std::unique_ptr klar, dass das Programm 
fehlerhaft ist und er könnte sehr wohl warnen, wenn er wollte.

Wie auch immer: Wenn die Priorität auf dangling Pointer um jeden Preis 
vermeiden liegt, hat Rust hier einen Punkt gemacht.

Finde ich.

vlg

Timm

P.S. Ich glaube mich persönlich holt das Beispiel jetzt nicht so ab, 
denn es zeigt ja nichts unerwartetes oder spezielles, genau so wie in 
dem Beispiel soll es ja sein, trotzdem ist der Rest-flavour des Themas 
natürlich einsteigerfreundlicher, eindeutiger und sicherer.

: Bearbeitet durch User
von S. R. (svenska)


Lesenswert?

nga schrieb:
> Ich habe mir mit C und C++ schon öfters effizient in den Fuß geschossen,
> was gerade auf µCs oft nicht direkt auffällt, das es keinen SegFault wie
> auf dem PC gibt

Den gibt es schon, heißt nur HardFault und führt normalerweise zu einem 
Reset. Unterbindet man das (z.B. durch einen eigenen HardFault-Handler), 
dann unterscheidet er sich nicht besonders von seinem PC-Pendanten. 
Weglaufende Pointer fängt man damit relativ gut ein.

nga schrieb:
> Rust vermeidet anscheinend ja effektiv Dangling Ponters und es gibt auch
> keine NULL-Pointer. Array-Bounds werden auch gecheckt. Das nimmt ja
> schon mal das meiste Gefahren-Potential.

Die meisten Gefahren kann man auch in C++ relativ zuverlässig 
verhindern, wenn man ein Stück weit von C weggeht. Referenzen sind z.B. 
oft eine gute Alternative zu Pointern und niemals NULL. Mit range-based 
for-loops lässt sich gut über Container iterieren, ohne dabei 
Arraygrenzen zu überschreiten (reduziert für mich einiges an 
Gefahrenpotential).

Viele (aber nicht alle) Array-Bounds lassen sich auch zur Compilezeit 
prüfen, und wenn man die überschreitet, gibt es nette Warnungen. Das ist 
alles nicht mehr so schlimm wie vor einigen Jahren.

Ansonsten haben die meisten modernen Sprachen ähnliche Features, z.B. 
muss man in Kotlin alle Variablen, die NULL sein können, entsprechend 
annotieren und den NULL-Fall auch durchgängig abfangen.

nga schrieb:
> Wie sieht es mit der Effizienz des erzeugtem Maschienencodes aus? Es
> wird ja LLVM benutzt, was ja schon einiges erwarten lässt (clang ist mWn
> auch ein LLVM-Frontend).

Die LLVM-Backends für x86 und ARM sind relativ gut, davon abgesehen wird 
es eher dünn. Clang ist das C/C++-Frontend für LLVM, es gibt aber noch 
sehr viele andere - wie eben z.B. für Rust.

Kaj schrieb:
> Man bekommt praktisch fuer alles einen Error, wo es in C/C++ noch
> nicht mal eine Warnung gibt bzw. nur, wenn man sie einschaltet.

Wer C/C++ mit weniger als "-Wall" benutzt, hat sämtliche daraus 
resultierenden Fehler selbst zu verantworten. Es sei denn, man gehört 
auch sonst zu denjenigen, die sich überall die Ohren zuhalten, um ja 
nicht ihre Realität hinterfragen zu müssen. :-)

Kaj schrieb:
> Ich arbeite mich gerade selber in Rust ein, allerdings erstmal auf dem
> Desktop unter Linux. Ich will es dann aber auch auf ARM und AVR nutzen.

Für ARM ist das vermutlich kein Problem, aber auf dem AVR kannst du das 
Thema vergessen. Selbst, wenn du es einigermaßen zum Laufen bekommst, so 
ist der LLVM-Support dafür eher mäßig.

von Yalu X. (yalu) (Moderator)


Lesenswert?

mh schrieb:
> Es ist kein Beispiel für Probleme mit smart-Pointern in c++, sondern
> eher für Probleme mit der move-Semantik.

Es ist ein Beispiel dafür, dass nach einem Move das betreffende Objekt
fehlerhafterweise weiter benutzt wird.

Der Rust-Compiler erkennt diesen Fehler garantiert, ein C++-Compiler
nicht unbedingt.

> Ok bei rust gibt der Compiler eine Meldung aus, die man aber auch in
> c++ bekommt, wenn man clang-tidy benutzt.

Ist das bei clang-tidy wirklich garantiert, auch in verzwickteren
Fällen? Mit welchen Optionen muss ich clang-tidy aufrufen, damit in
folgendem Beispiel der Fehler erkannt wird:

1
#include <iostream>
2
#include <memory>
3
4
void sub(std::unique_ptr<int> *up) {
5
  auto stolen = std::move(*up);
6
}
7
8
int main () {
9
  std::unique_ptr<int> orig(new int(5));
10
  std::cout << *orig << '\n';
11
  sub(&orig);
12
  std::cout << *orig << '\n';
13
}

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Hallo Yalu,

guter Punkt!
Wobei ich da doch eine Referenz bevorzugt hätte, als die altmodische C 
Variante, aber das ändert natürlich rein garnichts.

vlg

Timm

: Bearbeitet durch User
von Yalu X. (yalu) (Moderator)


Lesenswert?

Timm R. schrieb:
> Wobei ich da doch eine Referenz bevorzugt hätte, als die altmodische C
> Variante, aber das ändert natürlich rein garnichts.

Ich hatte ursprünglich eine Referenz verwendet, diese wurde aber von
clang-tidy angemeckert, weil ich mit -checks=* einfach mal blind alle
verfügbaren Prüfungen – und damit auch "google-runtime-references" –
aktiviert hatte:

  https://google.github.io/styleguide/cppguide.html#Reference_Arguments

> Eine Nachfrage: Kann ich in Rust das Äquivalent zu std::move auf Objekte
> anwenden, die nicht bewegbar sind?

Wie gesagt, ich bin noch sehr grün in Sachen Rust, weswegen ich diese
Frage nicht beantworten kann. Ich habe sie möglicherweise aber auch gar
nicht verstanden, oder warum sollte ein nicht bewegbares Objekt gemovet
(also bwegt) werden können? Das wäre doch ein Widerspruch in sich?

von mh (Gast)


Lesenswert?

Yalu X. schrieb:
> mh schrieb:
>> Es ist kein Beispiel für Probleme mit smart-Pointern in c++, sondern
>> eher für Probleme mit der move-Semantik.

Die Seite selbst behauptet aber, dass es ein Beispiel ist für "c++ 
smart-Pointer sind unsicher".

Yalu X. schrieb:
> ...folgendem Beispiel...
Ein raw-Pointer auf einen unique_ptr ... zum Glück ist es nur ein 
Beispiel. Wer sowas macht hat keine Warnung vom Compiler verdient ;-) .

Yalu X. schrieb:
> Ist das bei clang-tidy wirklich garantiert, auch in verzwickteren
> Fällen?
Nein. Ist es in rust garantiert?
Wie würde die folgende Funktion (zum Glück auch nur ein Beispiel) in 
rust aussehen und was sagt der Compiler, wenn er f1 und f2 nicht zur 
Compilezeit kennt?
1
std::unique_ptr<int> func(bool f1, bool f2, std::unique_ptr<int> &up) {
2
  std::unique_ptr<int> tmp;
3
  if(f1) {
4
    tmp = std::move(up);
5
  } else {
6
    tmp = std::unique_ptr<int>(new int(6));
7
  }
8
  if(f2) {
9
    std::cout << *up << std::endl;
10
  }
11
12
  return tmp;
13
}
Verbietet er die Funtkion, gibt er eine Warnung aus (clang-tidy 
bugprone*) oder macht er etwas anderes?

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

mh schrieb:

> Verbietet er die Funtkion, gibt er eine Warnung aus (clang-tidy
> bugprone*) oder macht er etwas anderes?

also ich habe keinen Schimmer von Rust, möchte aber gern eine Wette 
abgeben: Er verbietet es. Sonst würde imho das ganze Gezeter keinen Sinn 
ergeben.

Die Idee ist doch gerade, nur zuzulassen, was auch klappt, wenn der 
Entwickler nicht das falsche Gras geraucht hat. Dein Code kann aber in 
die Hose gehen. Also wette ich auf: Error.

Was ich dann auch nur folgerichtig und gut fände.

vlg
 Timm

: Bearbeitet durch User
von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Hallo,

kann hier jemand Rust? Könnte mir zufällig mal schnell jemand dies hier 
rosten? Die Definition von measure<> habe ich weggelassen, die wird man 
eh nicht 1:1 rosten können, ist aber auch egal. Ich würde gern mal damit 
in Tust experimentieren.

Ich würde es selbst versuchen, aber diese borrow mut Referenzen 
Geschichte, wäre nur trial & error.

vlg

 Timm
1
void mv2(std::vector<size_t>& a, std::vector<size_t>& b) {
2
    for(size_t i=0; i<100000; i++)
3
    {
4
        a = std::move(b);
5
        a[i]=42;
6
        b = std::move(a);
7
    }
8
}
9
10
11
int main(int argc, const char * argv[]) {
12
    std::vector<size_t> a{33, 100000};
13
    std::vector<size_t> b{34, 100000};
14
    auto timing = measure<std::chrono::microseconds>::execution(mv2, a, b);
15
    std::cout << b[100000-1] << " Zeit: " << timing << " µs" << std::endl;
16
    return 0;
17
}

: Bearbeitet durch User
von Bernd K. (prof7bit)


Lesenswert?

mh schrieb:
> Yalu X. schrieb:
>> Ist das bei clang-tidy wirklich garantiert, auch in verzwickteren
>> Fällen?
> Nein. Ist es in rust garantiert?

Selbstverständlich. Es ist Teil der Sprachdefinition, ein Verstoß gegen 
die Ownership-Regeln könnte nicht kompiliert werden, es wäre ungültiger 
Code und der Compiler würde mit Fehler abbrechen.

von mh (Gast)


Lesenswert?

Bernd K. schrieb:
> mh schrieb:
>> Yalu X. schrieb:
>>> Ist das bei clang-tidy wirklich garantiert, auch in verzwickteren
>>> Fällen?
>> Nein. Ist es in rust garantiert?
>
> Selbstverständlich. Es ist Teil der Sprachdefinition, ein Verstoß gegen
> die Ownership-Regeln könnte nicht kompiliert werden, es wäre ungültiger
> Code und der Compiler würde mit Fehler abbrechen.

In c++ gibt es nur im Fall f1=true f2=true ein Problem. Die drei anderen 
Fälle sind in Ordnung. Für rust ist das egal und es ist verboten?

Wo in der "Sprachdefinition" sind diese Ownership-Regeln definiert? Das 
was unter 
https://doc.rust-lang.org/stable/reference/memory-ownership.html steht 
ist nun wirklich nicht hilfreich.

von Bernd K. (prof7bit)


Lesenswert?

1
fn func(f1: bool, f2: bool, up: Box<i32>) -> Box<i32> {
2
    let mut tmp = Box::new(0);
3
    if f1 {
4
        tmp = up;
5
    }
6
    if f2 {
7
        println!("{}", up)
8
    }
9
    tmp
10
}
11
12
fn main() {
13
    let x = Box::new(42);
14
    func(true, true, x);
15
}
1
error[E0382]: use of moved value: `up`
2
 --> src/main.rs:7:24
3
  |
4
4 |         tmp = up;
5
  |               -- value moved here
6
...
7
7 |         println!("{}", up)
8
  |                        ^^ value used here after move
9
  |
10
  = note: move occurs because `up` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait
11
12
error: aborting due to previous error
13
14
For more information about this error, try `rustc --explain E0382`.
15
error: Could not compile `untitled2`.
16
17
To learn more, run the command again with --verbose.
18
19
Process finished with exit code 101

von Kaj (Gast)


Lesenswert?

mh schrieb:
> Wo in der "Sprachdefinition" sind diese Ownership-Regeln definiert?
Da:
https://doc.rust-lang.org/book/second-edition/ch04-01-what-is-ownership.html#what-is-ownership
1
Ownership Rules
2
3
First, let’s take a look at the ownership rules. Keep these rules in mind
4
as we work through the examples that illustrate them:
5
6
    Each value in Rust has a variable that’s called its owner.
7
    There can only be one owner at a time.
8
    When the owner goes out of scope, the value will be dropped.

von Kaj (Gast)


Lesenswert?

S. R. schrieb:
> aber auf dem AVR kannst du das Thema vergessen.
Warum? An dem Projekt wird aktiv gearbeitet: 
https://github.com/avr-rust/

von mh (Gast)


Lesenswert?

Kaj schrieb:
> mh schrieb:
>> Wo in der "Sprachdefinition" sind diese Ownership-Regeln definiert?
> Da:
> https://doc.rust-lang.org/book/second-edition/ch04...
Interessant, dass die Regeln nicht in der "The Rust Reference" stehen, 
sonder unter "Learning Rust".

Bernd K. schrieb:
> func(true, true, x);
Bei false false sagt er leider das gleiche.

Kaj schrieb:
> Ownership Rules
>
> First, let’s take a look at the ownership rules. Keep these rules in
> mind
> as we work through the examples that illustrate them:
>
>     Each value in Rust has a variable that’s called its owner.
>     There can only be one owner at a time.
>     When the owner goes out of scope, the value will be dropped.
Also für den false false Fall ist nach den Regeln alles in Ordnung.
Hat nen Owner.
Es gibt nur einen Owner.
Ist im Scope.

von Bernd K. (prof7bit)


Lesenswert?

mh schrieb:
> Also für den false false Fall ist nach den Regeln alles in Ordnung.
> Hat nen Owner.

Aber es könnte zur Laufzeit beide Fälle geben und deshalb ist der Code 
in dieser Form ungültig und kann nicht kompiliert werden.

von mh (Gast)


Lesenswert?

Bernd K. schrieb:
> mh schrieb:
>> Also für den false false Fall ist nach den Regeln alles in Ordnung.
>> Hat nen Owner.
>
> Aber es könnte zur Laufzeit beide Fälle geben und deshalb ist der Code
> in dieser Form ungültig und kann nicht kompiliert werden.

Ok, es sollte also gehen, wenn man den Fall true true verhindert:
1
    if f2 & (f1 == false) {
2
        println!("{}", up)
3
    }
Leider immer noch die gleiche Meldung.

von Jemand (Gast)


Lesenswert?

mh schrieb:
> Bernd K. schrieb:
>> mh schrieb:
>>> Also für den false false Fall ist nach den Regeln alles in Ordnung.
>>> Hat nen Owner.
>>
>> Aber es könnte zur Laufzeit beide Fälle geben und deshalb ist der Code
>> in dieser Form ungültig und kann nicht kompiliert werden.
>
> Ok, es sollte also gehen, wenn man den Fall true true verhindert:    if
> f2 & (f1 == false) {
>         println!("{}", up)
>     }
> Leider immer noch die gleiche Meldung.

Habe keine Ahnung von Rust, aber ich vermute es wird wie in anderen 
Sprachen auch behandelt: Wenn der Ausdruck nicht garantiert (unabhängig 
vom tatsächlichen Ausdruck!) während des Kompilierens ausgewertet werden 
kann, ist er so zu behandeln, als wäre das Ergebnis nur zur Laufzeit 
bekannt.
Das vereinfacht die Implementation und sorgt für konsistentes Verhalten.
Für mich ist das überhaupt nicht überraschend.

von Bernd K. (prof7bit)


Lesenswert?

mh schrieb:
> Leider immer noch die gleiche Meldung.

Man kann den Code auch so schreiben daß sich das Problem gar nicht erst 
stellt.
1
fn func(f1: bool, f2: bool, up: Box<i32>) -> Box<i32> {
2
    if f2 {
3
        println!("{}", up)
4
    }
5
6
    if f1 {
7
        up
8
    } else {
9
        Box::new(0)
10
    }
11
}

von Yalu X. (yalu) (Moderator)


Lesenswert?

mh schrieb:
> Wo in der "Sprachdefinition" sind diese Ownership-Regeln definiert? Das
> was unter
> https://doc.rust-lang.org/stable/reference/memory-ownership.html steht
> ist nun wirklich nicht hilfreich.

Das Reference-Dokument ist leider noch sehr unvollständig, was den
Autoren aber bewusst ist:

1
For now, this reference is a best-effort document. We strive for
2
validity and completeness, but are not yet there. In the future, the
3
docs and lang teams will work together to figure out how best to do
4
this. Until then, this is a best-effort attempt. If you find something
5
wrong or missing, file an issue or send in a pull request.

Zudem scheint die Sprachdefinition in einigen Punkten ohnehin noch im
Fluss zu sein.

Was die Regeln zur Überprüfung des Verlusts der Ownership betrifft, ist
der Compiler eher pessimistisch. Selbst in diesem Fall

1
  let a = Box::new(123);
2
  if false {
3
    let b = a;
4
  }
5
  print!("{}\n", a);

meckert der Compiler, obwohl es offensichtlich ist, dass der if-Zweig
nie ausgeführt wird.

Bei der Prüfung wird also wohl davon ausgegangen, dass jede if/while-
Bedingung unabhängig von dem tatsächlichen Ausdruck und unabhängig von
allen anderen if/while-Bedingungen einen beliebigen Wahrheitswert
annehmen kann. Wenn es unter dieser Annahme einen Pfad gibt, der zum
Zugriff auf ein nicht geowntes Objekt führt, wird ein Fehler ausgegeben.

Diese Regel erscheint auf den ersten Blick unnötig pessimistisch. Wenn
aber etwas darüber nachdenkt, kann man die Entscheidung durchaus
verstehen:

- Der Compiler sollte eher zu pessimistisch als zu optimistisch sein, so
  dass auf keinen Fall eine Verletzung der Ownership akzeptiert wird.
  Denn das würde das ganze schöne Konzept über den Haufen schmeißen.

- Ein perfekter Algorithmus zum Aufspüren von Verletzungen in beliebig
  komplizierten Code existiert nicht, da dieses Problem ebenso wenig
  entscheidbar ist wie das Halteproblem. Das Regelwerk muss also zu
  einem gewissen Grad pessimistisch sein.

- Es stellt sich nun die Frage, ob man

  - ein nahezu optimales, dafür aber sehr komplexes, oder

  - ein weniger optimales, dafür aber einfaches Regelwerk bevorzugt.

  Die Rust-Entwickler haben sich offensichtlich für die zweite Option
  entschieden. Das ist IMHO auch gut so, denn die Koplexität des
  Regelwerks betrifft ja nicht nur die Compilerbauer, sondern jeden
  Rust-Programmierer.

Ich vermute, dass in realem Code die Fälle, wo der Compiler einen Fehler
meldet, obwohl bei genauerer Analyse keine Verletzung der Ownership
vorliegt, sehr selten sind. Sollte dieser Fall dennoch einmal auftreten,
kann das Problem sicher durch eine leichte Umstrukturierung des Codes
behoben werden, was den angenehmen Nebeneffekt hat, dass der Code etwas
entworren wird.

von Bernd K. (prof7bit)


Lesenswert?

Yalu X. schrieb:
> Ich habe mich bisher nur wenig mit Rust beschäftigt, halte es aber für
> eine der interessantesten Programmiersprachen aus jüngerer Zeit.

Ebenso. Es erscheinen regelmäßig neue Sprachen auf der Bildfläche die 
einen nicht wirklich vom Hocker reißen und keine wirklich neuen Konzepte 
einführen und verschwinden bald wieder in der Versenkung aber nur alle 
paar Schaltjahre taucht mal ein Stern am Programmiersprachenhimmel auf 
der sich wirklich von der Masse abhebt.

Und dann auch noch eine Sprache deren Kompilat ohne Runtime auskommt und 
damit in direkte Konkurrenz mit C(++) tritt und somit auch für kleinste 
µC interessant ist, solche Sprachen kann man fast an einer Hand 
abzählen.

Rust steht mittlerweile auch bei mir ganz oben auf meiner Liste der 
Sprachen in die ich gerne etwas tiefer einsteigen will.

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Bernd K. schrieb:
>
> Und dann auch noch eine Sprache deren Kompilat ohne Runtime auskommt

Hallo,

sorry, kann mir jemand erklären, was das bedeutet? Heißt das, man kann 
Rust nicht dynamisch linken? Warum ist das gut?

Viele liebe Grüße
timm

von Yalu X. (yalu) (Moderator)


Lesenswert?

Timm R. schrieb:
> Bernd K. schrieb:
>>
>> Und dann auch noch eine Sprache deren Kompilat ohne Runtime auskommt
>
> Hallo,
>
> sorry, kann mir jemand erklären, was das bedeutet?

Bernd mein vermutlich so etwas wie bei Java oder C#, wo man ein
Riesenpaket an Bibliotheken und sonstigem Gedöns installieren muss,
bevor man die erste kleine Anwendung starten kann.

> Heißt das, man kann Rust nicht dynamisch linken?

Doch, das geht schon.

Auf Plattformen ohne Betriebssystem gibt es aber meist weder einen
dynamischen Linker noch ein Filesystem, vom dem die dynamischen
Bibliotheken geladen werden können. Da möchte man die komplette
Anwendung mit allem, was dazugehört, statisch in ein einziges Executable
linken.

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Yalu X. schrieb:
> Timm R. schrieb:
>> Bernd K. schrieb:
>>>
>>> Und dann auch noch eine Sprache deren Kompilat ohne Runtime auskommt
>>
>> Hallo,
>>
>> sorry, kann mir jemand erklären, was das bedeutet?
>
> Bernd mein vermutlich so etwas wie bei Java oder C#, wo man ein
> Riesenpaket an Bibliotheken und sonstigem Gedöns installieren muss,
> bevor man die erste kleine Anwendung starten kann.

ach soo! Alles klar, danke. Ich dachte, das ginge gegen c/c++ und das 
ist ja wirklich mal eine Stelle, wo bei c/c++ alles proper ist.

vlg und danke
Timm

von Bernd K. (prof7bit)


Lesenswert?

Timm R. schrieb:
> Hallo,
>
> sorry, kann mir jemand erklären, was das bedeutet?

Nein, das bedeutet daß Rust (genau wie C oder C++ auch) sich gut für 
bare metal eignet, weil es zu nativem Code kompiliert der läuft ohne 
viel mehr als nur sich selbst zu benötigen, man kann große Teile der 
Standard Library welche dynamische Speicherallokation benutzen einfach 
weglassen und die Sprache mit dem was übrig bleibt immer noch benutzen 
(und die wichtigen Sprachfeatures immer noch funktionieren) und braucht 
dann nur noch die üblichen paar hundert Byte Startupcode (wie bei C++ 
auch) um den Prozessor zu initialisieren und den nackten kompilierten 
Rust-Code.

Runtime wäre sowas wie zum Beispiel ein immer zwingend vorhandener 
Garbage-Collector (das gibts nicht in Rust) oder gar eine riesige VM 
(wie in Java oder C#) die gleich mal mit vergleichsweise riesigem 
Overhead daherkommen selbst beim kleinsten Hello World.

Bei Rust kann man es so einrichten daß man genau wie bei C oder C++ 
wirklich nur noch die selbst geschriebenen Funktionen im Kompilat hat 
und sonst praktisch so gut wie nichts mehr (nicht mehr als man auch 
hätte wenn man es in C++ gemacht hätte) und die laufen so wie sie sind 
direkt auf dem blanken Silizium.

> Heißt das, man kann
> Rust nicht dynamisch linken? Warum ist das gut?

Das hat damit gar nichts zu tun.

Eher im Gegenteil ist es so daß man bei den oben genannten "gemanageten" 
Sprachen die innerhalb einer VM ablaufen arge Klimmzüge machen muß oder 
umständliche Wrapper braucht um sie in die eine oder andere Richtung mit 
C Kompilaten zu linken (falls überhaupt möglich).

Mit Rust kann man selbstverständlich Code erzeugen der sich mit C oder 
C++ problemlos und ganz direkt dynamisch oder statisch linken lässt. 
Darauf hat man absichtlich Wert gelegt.

Rust ist in dieser Hinsicht wie C, nur die eigentliche Sprache ist 
komplett anders und besser.

von W.S. (Gast)


Lesenswert?

Bernd K. schrieb:
> Mit Rust kann man selbstverständlich Code erzeugen der sich mit C oder
> C++ problemlos...

.. zusammenlinken läßt. Naja, eben.

Rust ist ganz offensichtlich nur ein weiterer Vorbrenner für C. Sieht ja 
auch fast genauso aus, ist nur noch ein wenig unübersichtlicher.

W.S.

von Dr. Sommer (Gast)


Lesenswert?

Genau, schließlich wissen wir ja alle dass die Optik bei einer 
Programmiersprache am Wichtigsten ist. Deswegen ist ja z.B. auch die 
Shakespeare Programming Language eine der Beliebtesten.

von Bernd K. (prof7bit)


Lesenswert?

W.S. schrieb:
> weiterer Vorbrenner für C. Sieht ja
> auch fast genauso aus,

Nur daß es eigentlich komplett anders aussieht.

Und nein, es wird nicht in irgendeinem Zwischenschritt nach C 
kompiliert, C kommt überhaupt nicht vor, das verwechselst Du 
wahrscheinlich mit irgendeiner anderen Sprache. Der Compiler verwendet 
LLVM und spuckt direkt das native Binary aus.

von Markus F. (mfro)


Lesenswert?

W.S. schrieb:
> Rust ist ganz offensichtlich nur ein weiterer Vorbrenner für C. Sieht ja
> auch fast genauso aus, ist nur noch ein wenig unübersichtlicher.

man merkt gleich, dass Du dich ganz genau informiert hast.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Markus F. schrieb:
> W.S. schrieb:
>> Rust ist ganz offensichtlich nur ein weiterer Vorbrenner für C. Sieht ja
>> auch fast genauso aus, ist nur noch ein wenig unübersichtlicher.
>
> man merkt gleich, dass Du dich ganz genau informiert hast.

Für W.S. ist alles C, was nicht Pascal ist ;-)

Versuchen wir aber trotzdem, die Diskussion auf das vom TE vorgegebene
Thema, nämlich Rust (im Vergleich zu C und C++) zu beschränken!

von Yalu X. (yalu) (Moderator)


Angehängte Dateien:

Lesenswert?

Timm R. schrieb:
> Könnte mir zufällig mal schnell jemand dies hier rosten?

Ich hab's mal versucht.

Allerdings habe ich das da nicht ganz verstanden:

1
    std::vector<size_t> a{33, 100000};
2
    std::vector<size_t> b{34, 100000};

Damit werden zwei Vektoren mit je zwei Elementen angelegt, was hier

1
    for(size_t i=0; i<100000; i++)
2
    {
3
        a = std::move(b);
4
        a[i]=42;
5
        b = std::move(a);
6
    }

unweigerlich zum Crash führt. Ich nehme an, es sollte

1
    std::vector<size_t> a(100000, 33);
2
    std::vector<size_t> b(100000, 34);

heißen (jeweils 100000 Elemente mit dem Wert 33 bzw. 34).

movetest1.rs wäre die 1:1-Umsetzung deines Codes. Das kompiliert aber
nicht, weil in mv2 versucht wird, die mittels Referenzen geborgten
Objekte zu moven. Das ist genauso, als würdest du dein Auto einem Freund
leihen und dieser es an einen Dritten verschenken oder es gleich auf den
Schrottplatz bringen :)

In C++ ist das zwar prinzipiell erlaubt, und sogar clang-tidy akzeptiert
das, trotzdem muss man beachten, dass nach dem Aufruf von mv2 der Vektor
a weggemovet worden ist und keine sinnvollen Daten mehr enthält.

Rust hat bzgl. geborgter Objekte (d.h. Referenzen auf Objekte) strengere
Regeln.

Alternativ zu Referenzen könnte man a und b per move an mv2 übergeben,
allerdings hat man dann hinterher keinen Zugriff mehr darauf, so dass
die Ausgabe des Elements von b angemeckert wird.

Man könnte a und b auch klonen, nur bekommt dann das Hauptprogramm die
in mv2 vorgenommenen Änderungen nicht mehr mit.

Wenn man die Argumentübergabe umgeht, indem man die Schleife ins
Hauptprogramm verlagert, gibt es keine Probleme. So habe ich es in
movetest2.rs schließlich gemacht.

movetest.cpp ist dein leicht modifizierter C++-Code. Damit bei der
Zeitmessung der Aufruf-Overhead von mv2 nicht mitgemessen wird, habe ich
sie in die Funktion mit hinein gepackt.

Die Compileraufrufe:
1
clang++ -Wall -std=c++17 -O3 -o movetestc movetest.cpp
2
g++     -Wall -std=c++17 -O3 -o movetestg movetest.cpp
3
rustc -C opt-level=3 movetest.rs

Die gemessenen Zeiten auf zwei Laptops mit unterschiedlichen CPUs:
1
        i7-4910MQ     i5-6267U
2
———————————————————————————————
3
Clang    512.8 ms     611.8 ms
4
GCC      513.2 ms     611.8 ms
5
Rust     526.4 ms     526.4 ms
6
———————————————————————————————

Noch ein Hinweis: Wenn du mit dem C++-Code herumspielst und feststellst,
dass der Clang-Code plötzlich um den Faktor 6 schneller als der GCC-Code
ist, liegt das daran, dass der Clang die Funktion mv2 inlinet und dabei
einen Großteils des Codes wegoptimiert. Mit __attribute__(noinline))
kann das ggf. vermieden werden.

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Hallo Yalu,

ja hatte das auf dem handy hingetippert. Wie blöd. War wohl dann 
schonmal eine kleine Werbung für Rust :-)

Vielen Dank! Sehr nett von dir!

Viele liebe Grüße
timm

von Kaj (Gast)


Lesenswert?

Hey Yalu,

du hast da einen kleinen Fehler in deinem Code.

In movetest1.rs hast du:
1
  for i in 0..N {
2
    *a = *b;
3
    b[i] = 42;  // !!!
4
    *b = *a;
5
  }

Und in movetest2.rs hast du aber:
1
  for i in 0..N {
2
    a = b;
3
    a[i] = 42;  // !!!
4
    b = a;
5
  }

Aendert man in movetest2.rs das a[i] zu b[i], dann compiliert es auch 
nicht mehr.
1
warning: value assigned to `a` is never read
2
 --> src/main.rs:6:11
3
  |
4
6 |   let mut a = vec![33usize; N];
5
  |           ^
6
  |
7
  = note: #[warn(unused_assignments)] on by default
8
9
error[E0382]: use of moved value: `b`
10
  --> src/main.rs:13:5
11
   |
12
12 |     a = b;
13
   |         - value moved here
14
13 |     b[i] = 42;
15
   |     ^ value used here after move
16
   |
17
   = note: move occurs because `b` has type `std::vec::Vec<usize>`, which does not implement the `Copy` trait
18
19
error: aborting due to previous error
20
21
For more information about this error, try `rustc --explain E0382`.
22
error: Could not compile `test_prog`.
Kurz: Egal wie du es machst, es geht nicht. :D

Yalu X. schrieb:
> Man könnte a und b auch klonen, nur bekommt dann das Hauptprogramm die
> in mv2 vorgenommenen Änderungen nicht mehr mit.
Da sich das Beispiel anscheinend nicht 1:1 in Rust umsetzen laesst, 
warum a und b nicht einfach als Tuple (oder sonstwas) zurueck geben?

Gruesse

von Timm R. (Firma: privatfrickler.de) (treinisch)


Angehängte Dateien:

Lesenswert?

Hallo Yalu,

Yalu X. schrieb:
> Die gemessenen Zeiten auf zwei Laptops mit unterschiedlichen CPUs:
>         i7-4910MQ     i5-6267U
> ———————————————————————————————
> Clang    512.8 ms     611.8 ms
> GCC      513.2 ms     611.8 ms
> Rust     526.4 ms     526.4 ms
> ———————————————————————————————

hmhm, da stellt sich doch die Frage, warum das mit Clang und GCC auf 
meinem i7-6700K CPU @ 4.00GHz 10 ms langsamer ist, als auf Deinem 
i5-6267U. Das ist irgendwie ungerecht :-)

Danke, genau so, wie du es programmiert hast, war es gedacht.

1. Mein Fehler mit den {} ist ein Punkt für Rust
2. Habe ich die Timings zum Anlass genommen, die Behauptung des OP, 
Zugriffe seien Range-checked zu überprüfen: Das stimmt nicht, Zugriffe 
sind nicht range-checked.
3. Diese move-Sache interessiert mich. Hätte man nicht erwartet, dass 
Rust viel schneller ist? Ich dachte, ich hätte gelesen, dass Rust den 
Speicher als Block kopiert. C++ geht ja über alle Elemente und ruft den 
Move Konstruktor auf, was bei szie_t natürlich nichts bringt?

Mit String statt size_t ist dann bei mir der C++ move vermutlich im 
Vorteil.

Rust braucht 5.28s, Clang 1.62s

vlg

 Timm

von Bernd K. (prof7bit)


Lesenswert?

Timm R. schrieb:
> Hätte man nicht erwartet, dass
> Rust viel schneller ist? Ich dachte, ich hätte gelesen, dass Rust den
> Speicher als Block kopiert.

Rust muß doch beim Eigentümerwechsel zur Laufzeit gar nichts mehr 
machen. Das Objekt liegt irgendwo im Speicher und der Compiler hat schon 
zur Compilezeit sichergestellt daß die Eigentumsverhältnisse überall 
korrekt sind, es geht ja nur darum daß der Compiler keinen Code erzeugen 
kann bei dem ein Teil des Programms dem anderen unerwartet die Variablen 
unter den Füßen wegziehen kann. Sobald der Code so geschrieben ist daß 
das niemals geschehen kann muß beim eigentlchen move zur Laufzeit gar 
nichts mehr geschehen.

von mh (Gast)


Lesenswert?

Timm R. schrieb:
> 1. Mein Fehler mit den {} ist ein Punkt für Rust

Wieso ist dein Fehler ein Punkt für rust?
In rust ist auch relevant was man genau schreibt:
1
let v = vec![10, 5];
2
let w = vec![10; 5];

Timm R. schrieb:
> 3. Diese move-Sache interessiert mich. Hätte man nicht erwartet, dass
> Rust viel schneller ist? Ich dachte, ich hätte gelesen, dass Rust den
> Speicher als Block kopiert. C++ geht ja über alle Elemente und ruft den
> Move Konstruktor auf, was bei szie_t natürlich nichts bringt?

In dem Beispiel wird ein std::vector gemoved. Es wird nicht jedes 
Element gemoved. Einen std::vector zu moven bedeutet 3 Pointer zu 
kopieren.

von W.S. (Gast)


Lesenswert?

Yalu X. schrieb:
> Für W.S. ist alles C, was nicht Pascal ist ;-)

OK, ich revidiere das mal dahingehend, daß Rust sowohl wie C als auch 
wie Basic aussieht:
1
fn main() {
2
  let mut a = vec![33usize; N];
3
  let mut b = vec![34usize; N];
4
  let start = Instant::now();

Es fehlen bloß die Zeilennummern und 'dim'.
100 let a = 123
101 gosub 200

oder so ähnlich. Ist mir schon zu lange her.

Also was soll sowas bloß? Offenbar schmeißt Rust mit noch mehr 
Interpunktionszeichen um sich als C - und das will schon was heißen.

Aber mit dem Vorbrenner für C hatte ich schon Recht. Zitat: "On Windows, 
Rust additionally requires the C++ build tools for Visual Studio 2013 or 
later."

W.S.

von Bernd K. (prof7bit)


Lesenswert?

W.S. schrieb:
> OK, ich revidiere das mal dahingehend, daß Rust sowohl wie C als auch
> wie Basic aussieht:

Alter Schwede, was für ein saublödes Geschwätz. W.S. wie er leibt und 
lebt wieder mal. Echt original.

von Yalu X. (yalu) (Moderator)


Angehängte Dateien:

Lesenswert?

Kaj schrieb:
> du hast da einen kleinen Fehler in deinem Code.
>
> In movetest1.rs hast du:  for i in 0..N {
>     *a = *b;
>     b[i] = 42;  // !!!
>     *b = *a;
>   }

Du hast recht, da sollte
1
a[i] = 42;

stehen wie von Timm hier vorgegeben:

Timm R. schrieb:
> a[i]=42;

Die Fehlermeldungen bleiben aber die gleichen und beziehen sich auf das
*a = *b und *b = *a.

In movetest2.rs ist die entsprechende Zeile richtig.

Kaj schrieb:
> Yalu X. schrieb:
>> Man könnte a und b auch klonen, nur bekommt dann das Hauptprogramm die
>> in mv2 vorgenommenen Änderungen nicht mehr mit.
> Da sich das Beispiel anscheinend nicht 1:1 in Rust umsetzen laesst,
> warum a und b nicht einfach als Tuple (oder sonstwas) zurueck geben?

Stimmt. Es würde sogar reichen, b zurückzugeben, da a ja sowieso
zermovet ist (auch im Original-C++-Code von Timm) und auch gar nicht
mehr benötigt wird. Ich habe das mal in movetest3.rs so umgesetzt.

: Bearbeitet durch Moderator
von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Hallo Bernd,

Bernd K. schrieb:
> Timm R. schrieb:
>> Hätte man nicht erwartet, dass
>> Rust viel schneller ist? Ich dachte, ich hätte gelesen, dass Rust den
>> Speicher als Block kopiert.
>
> Rust muß doch beim Eigentümerwechsel zur Laufzeit gar nichts mehr
> machen.

meine Worte, bzw.: um so erstaunlicher. 500-600 ms ist eine lange Zeit 
für "nichts" ... (Siehe Yalus Timings)

vlg

 Timm

von Yalu X. (yalu) (Moderator)


Lesenswert?

Timm R. schrieb:
> hmhm, da stellt sich doch die Frage, warum das mit Clang und GCC auf
> meinem i7-6700K CPU @ 4.00GHz 10 ms langsamer ist, als auf Deinem
> i5-6267U. Das ist irgendwie ungerecht :-)

Da sich die Prozessoren im Pipelining und in der Branch-Prediction stark
unterscheiden, kann es schon passieren, dass der eigentlich schnellere
Prozessor in bestimmten Fällen langsamer ist.

Als ich einmal mit einem Stückchen Code die Geschwindigkeit von C und
Haskell vergleichen wollte, stellte ich überrascht fest, dass der
Haskell-Code etwa 50% schneller war. Noch überraschter war, als ich den
vom C-Compiler generierten Assemblercode analysierte, der nach meinem
Dafürhalten nicht weiter optimierbar war, höchstens mit einem mir
unbekannten Programmiertrick. Also habe ich im vom Haskell-Compiler
generierten Assemblercode nach diesem Programmiertrick gesucht, musste
aber feststellen, dass dieser Code zwar nicht schlecht, aber dennoch
umständlicher war das der vom C-Compiler generierte. Ich vermute
deswegen, dass der Haskell-Code einfach besser mit dem Piplining des
Prozessors harmoniert hat. Auf einem anderen Prozessor war der C-Code
schneller.

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

mh schrieb:

> In dem Beispiel wird ein std::vector gemoved. Es wird nicht jedes
> Element gemoved. Einen std::vector zu moven bedeutet 3 Pointer zu
> kopieren.

und dafür braucht c++ 500 ms? Dann sollte man sich tatsächlich ernsthaft 
überlegen, die Sprache zu wechseln.

vlg
 Timm

von Yalu X. (yalu) (Moderator)


Lesenswert?

Bernd K. schrieb:
> Rust muß doch beim Eigentümerwechsel zur Laufzeit gar nichts mehr
> machen.

Da bin ich mir nicht so sicher, bin aber noch nicht weit genug in die
Tiefen von Rust abgestiegen, um das sicher beurteilen zu können. Im
konkreten Beispiel hätte der Compiler das Kopieren vermutlich
wegoptimieren können, aber das geht nicht immer:

In folgendem Beispiel

1
  let a = ...;
2
  let b = ...;
3
  if ... {
4
    b = a;
5
  }
6
  machwasmit(b);

ist b beim Aufruf von machwasmit entweder das ursprüngliche b oder das
ursprüngliche a, jenachdem, ob die if-Bedingung falsch oder wahr ist.
Deswegen muss bei b = a mindestens eine Shallow-Copy gemacht werden.

Immerhin kann durch das Moven auf eine Deep-Copy verzichtet werden, und
durch die Prüfung der Ownership zur Compilezeit ist der Code auch ohne
Overhead durch Laufzeitprüfungen sicher.

von mh (Gast)


Lesenswert?

Timm R. schrieb:
> meine Worte, bzw.: um so erstaunlicher. 500-600 ms ist eine lange Zeit
> für "nichts" ... (Siehe Yalus Timings)

Der "Eigentümer" muss immer noch gewechselt werden, was etwas mehr als 
"nichts" ist. Wenn a[i] (oder b[i])  einen Seiteneffekt hat, wie z.b. 
Rangecheck mit evtl. panic (k.a. was da genau im Hintergrund passiert), 
kann die Schleife auch nicht wirklich optimiert werden.

Timm R. schrieb:
> mh schrieb:
>
>> In dem Beispiel wird ein std::vector gemoved. Es wird nicht jedes
>> Element gemoved. Einen std::vector zu moven bedeutet 3 Pointer zu
>> kopieren.
>
> und dafür braucht c++ 500 ms?
Nein, die 800e6 Bytes wollen auch kopiert werden.

Timm R. schrieb:
> Dann sollte man sich tatsächlich ernsthaft
> überlegen, die Sprache zu wechseln.
Oder eine der Sprachen richtig lernen, damit du verstehst was alles im 
Hintergrund passiert?!

von Yalu X. (yalu) (Moderator)


Lesenswert?

W.S. schrieb:
> OK, ich revidiere das mal dahingehend, daß Rust sowohl wie C als auch
> wie Basic aussieht:fn main() {
>   let mut a = vec![33usize; N];
>   let mut b = vec![34usize; N];
>   let start = Instant::now();
>
> Es fehlen bloß die Zeilennummern und 'dim'.
> 100 let a = 123
> 101 gosub 200

Ja, dein scharfes Auge hat in beiden Beispielen das Schlüsselwort "let"
entdeckt. Herzlichen Glückwunsch dafür ;-)

Ist dir schon einmal in den Sinn gekommen, dass dieses "let" in Rust
eine gänzlich andere Bedeutung haben könnte als in Basic?

Beitrag #5516440 wurde von einem Moderator gelöscht.
von Privatfrickler (Gast)


Angehängte Dateien:

Lesenswert?

Mir fehlt ein wenig die Einsicht was euer Code hier eigentlich soll???

Im Endeffekt lasst ihr 3 Pointer zwischen a und b immer sinnlos hin- und 
herpendeln (siehe Anhang!). Wenn der Compiler schlau genug wäre könnte 
er eigentlich über eine genauere "Laufzeit-Vorab-Analyse" nach ein paar 
Durchläufen erkennen, dass hier sinnlos im Kreis gepointert wird 
(Ringelrein mit Adressen) und den Code dazu anstatt Millionen mal 
schlicht zweimal ausführen a[] -> b[] -> a[] und gut ist.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Timm R. schrieb:
> meine Worte, bzw.: um so erstaunlicher. 500-600 ms ist eine lange Zeit
> für "nichts" ... (Siehe Yalus Timings)

Das sind 5-6 ns pro Schleifendurchlauf, d.h 2 Moves, 1 Zuweisung des
Array-Elements und Schleifenoverhead.

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

mh schrieb:

>>> In dem Beispiel wird ein std::vector gemoved. Es wird nicht jedes
>>> Element gemoved. Einen std::vector zu moven bedeutet 3 Pointer zu
>>> kopieren.
>>
>> und dafür braucht c++ 500 ms?
> Nein, die 800e6 Bytes wollen auch kopiert werden.

Du wolltest also schreiben:

Einen std::vector zu moven bedeutet 3 Pointer und den gesamten 
Speicherbereich der Elemente zu kopieren?

Das ist aber nicht genau das selbe.

>Oder eine der Sprachen richtig lernen

Deutsch zum Beispiel?


vlg
 Timm

von mh (Gast)


Lesenswert?

Timm R. schrieb:
> Du wolltest also schreiben:
>
> Einen std::vector zu moven bedeutet 3 Pointer und den gesamten
> Speicherbereich der Elemente zu kopieren?
Nein!
1
//ein vector mit 1000 ints
2
std::vector<int> foo(1000);
3
4
//hier werden 3 Pointer kopiert
5
auto baa = std::move(foo);
6
7
// in dieser Schleife werden 6000 Pointer werden kopiert und 1000 ints werden geschrieben
8
for(int i=0; i<1000; ++i) {
9
  foo = std::move(baa); // 3 Pointer werden kopiert
10
  foo[i] = 42; // ein int wird in den Speicher geschrieben
11
  baa = std::move(foo); // 3 Pointer werden kopiert
12
}

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Hallo,

diese move-Thema interessiert mich weiterhin.
Und danach, wie rüde und selbstsicher die Antworten formuliert sind zu 
gehen, bin ich wohl der Einzige, dem sich kein einheitliches Bild 
ergibt.

1. Warum genau ist die Move-Operation bei Rust so viel schneller, als 
bei clang c++?
2. Warum bricht die Performance so stark ein, wenn es sich nicht um 
einen vector von size_t sondern von string handelt?

std::string
clang: 1452 ms
rust: 5275 ms

size_t
clang: 831 ms
rust: 488 ms

rustc 1.28.0
LLVM version 9.1.0

Vielen Dank

 Timm

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

mh schrieb:
> Timm R. schrieb:
>> Du wolltest also schreiben:
>>
>> Einen std::vector zu moven bedeutet 3 Pointer und den gesamten
>> Speicherbereich der Elemente zu kopieren?
> Nein!

Ich bitte um Entschuldigung und danke für die Klarstellung. Da hatte ich 
wohl Tomaten auf den Ohren!

vlg

 Timm

von Jürgen S. (starblue) Benutzerseite


Lesenswert?

nga schrieb:
>
> Was ich mich noch frage: was passiert standardmäßig im Falle eines
> panic!()-Aufrufs?

Mikrokontroller programmiert man normalerweise ohne die 
Standardbibliothek,
die sonst das Panik-Handling macht (Direktive #[no_std]).
Darum muss es irgendwo einen Panik-Handler geben, für den Anfang reicht 
eine Endlosschleife:
1
use core::panic::PanicInfo;
2
3
#[panic_implementation]
4
fn panic(_info: &PanicInfo) -> ! {
5
    loop {}
6
}

Es gibt auch fertige Handler, die wohl per cortex-m-rt eingebunden 
werden sollen (panic-semihosting, panic-abort), hab ich aber noch nicht 
ausprobiert.

von mh (Gast)


Lesenswert?

Timm R. schrieb:
> 1. Warum genau ist die Move-Operation bei Rust so viel schneller, als
> bei clang c++?
> 2. Warum bricht die Performance so stark ein, wenn es sich nicht um
> einen vector von size_t sondern von string handelt?
> std::string
> clang: 1452 ms
> rust: 5275 ms
> size_t
> clang: 831 ms
> rust: 488 ms
Was genau vergleichst du? Am besten du zeigst den Quelltext der beiden 
Programme mit denen du testest.

von Alex G. (dragongamer)


Angehängte Dateien:

Lesenswert?

Timm R. schrieb:
> Könnte sich denn vielleicht einer der Rust-kundigen und C++-kundigen
> erbarmen, mal ein minimales Beispiel mit c++ Pointer-Katastrophe zu
> zeigen und wie es in Rust besser läuft? Das wäre doch sicher für mehrere
> Rist-Unkundige interessant und erhellend? Mir fehlt da einfach die
> Vorstellungskraft.

Hmm, du hättest bei meinem Vortrag vor ein paar Wochen über Rust dabei 
sein sollen.
Dafür habe ich den Heartbleed Bug in C++ nachprogrammiert - und dann 
versucht ihn auch unter Rust zu programmieren (ohne Unsafe).
Letzteres war nicht möglich.
In der angehängten Datei sind zwei Versionen drin - eine die zur 
Compilezeit schon Error wirft und eine die die falsche 
Array-Längenangabe garnicht nutzen kann.

von mh (Gast)


Lesenswert?

Alex G. schrieb:
> Hmm, du hättest bei meinem Vortrag vor ein paar Wochen über Rust dabei
> sein sollen.
Wo hast du diesen Vortrag gehalten?

Alex G. schrieb:
> Dafür habe ich den Heartbleed Bug in C++ nachprogrammiert
Du hast den "Bug" in c programmiert und dann iostream benutzt, damit du 
es c++ nennen darfst. Für ein echtes c++ Beispiel hättest du zumindest 
std::string und/oder std::vector nutzen müssen. Der eigentliche Bug in 
deinem Programm ist übrigens ein memory leak.


Wo in deiner HeartbleedDemo.cpp ist eigentlich die
1
template <typename T>
2
void return(T)
deklariert/definiert? ;-)

von Arc N. (arc)


Lesenswert?

Bernd K. schrieb:
> mh schrieb:
>> Yalu X. schrieb:
>>> Ist das bei clang-tidy wirklich garantiert, auch in verzwickteren
>>> Fällen?
>> Nein. Ist es in rust garantiert?
>
> Selbstverständlich. Es ist Teil der Sprachdefinition, ein Verstoß gegen
> die Ownership-Regeln könnte nicht kompiliert werden, es wäre ungültiger
> Code und der Compiler würde mit Fehler abbrechen.

Selbst wenn es Teil der Sprachdefinition ist, ist das keine Garantie für 
irgendwas. Das gilt im übrigen auch für alle anderen Garantien die Rust 
geben will. Formale Beweise kommen so langsam, zumindest für eine gute 
Untermenge von Rust, 
https://people.mpi-sws.org/~dreyer/papers/rustbelt/paper.pdf
Appendix und weiteres gibt's unter 
https://plv.mpi-sws.org/rustbelt/popl18/
Weniger formal erklärt inkl. der noch fehlenden Teile 
https://blog.acolyer.org/2018/01/18/rustbelt-securing-the-foundations-of-the-rust-programming-language/

von Alex G. (dragongamer)


Lesenswert?

mh schrieb:
> Alex G. schrieb:
>> Hmm, du hättest bei meinem Vortrag vor ein paar Wochen über Rust dabei
>> sein sollen.
> Wo hast du diesen Vortrag gehalten?
Hochschule Master in einem Kurs über "Secure Systems".
Haupthema war allerdings eher "Rust Belt"; ein mathematischer Ansatz der 
die Sicherheit von Rust's Standard library nachweist obwohl diese intern 
"unsafe" benutzt.

EDIT: Sehe grade, Arc. N hat genau darauf Bezug genommen!
Mag vielleicht noch nicht vollständig sein, aber ist noch immer 
erheblich mehr als was es für jede andere brauchbare Sprache gibt.

"Besseres" gibt es nur in Sprachen die umgekehrt entwickelt wurden: Erst 
sicheres mathematisches Konstrukt, dann darauf eine Art von Sprache.
Nur will man das Zeug als Programmierer der sein Geld durch einigermaßen 
effizientes Arbeiten verdienen muss, nicht mal mit der Kneifzange 
anfassen...

> Alex G. schrieb:
>> Dafür habe ich den Heartbleed Bug in C++ nachprogrammiert
> Du hast den "Bug" in c programmiert und dann iostream benutzt, damit du
> es c++ nennen darfst. Für ein echtes c++ Beispiel hättest du zumindest
> std::string und/oder std::vector nutzen müssen. Der eigentliche Bug in
> deinem Programm ist übrigens ein memory leak.
Der Heartbleed war doch im Grunde ein Memoryleak. Halt über die 
Systemgrenze hinweg.

Gut, das ist C. Sollte eben so leicht lesbar wie möglich sein. In dem 
Fall brauchte es auch eher keine Objektorientierung ;)

> Wo in deiner HeartbleedDemo.cpp ist eigentlich die
>
1
> template <typename T>
2
> void return(T)
3
>
> deklariert/definiert? ;-)
Das verstehe ich jetzt aber nicht so ganz. Wofür wäre ein Template gut 
gewesen?

Achso, damit es mehr nach C++ klingt? :P

: Bearbeitet durch User
von mh (Gast)


Lesenswert?

Alex G. schrieb:
> Der Heartbleed war doch im Grunde ein Memoryleak. Halt über die
> Systemgrenze hinweg.
Nein! Bei Heartbleed kann man Speicher lesen, den man nicht lesen können 
sollte. Ein Programm hat ein memory leak, wenn es Speicher allokiert 
hat, auf den niemand mehr zugreifen kann. Und welche Systemgrenze meinst 
du?

Alex G. schrieb:
> Gut, das ist C. Sollte eben so leicht lesbar wie möglich sein.
Warum hast du es dann c++ genannt? Hättest du strings/vectoren genommen, 
könntest du testAliveA und testAliveB analog zu deinen rust Versionen 
schreiben und das es existiert nicht.

Alex G. schrieb:
> In dem Fall brauchte es auch eher keine Objektorientierung
Aber jemanden, der c++ als c mit Objekten sieht, hat die Sprache nicht 
verstanden. Bleibt die Frage: Warum vergleicht man c++ mit rust, wenn 
man kein c++ kann?

Alex G. schrieb:
> Das verstehe ich jetzt aber nicht so ganz. Wofür wäre ein Template gut
> gewesen?
>
> Achso, damit es mehr nach C++ klingt? :P
Nein, aber ich habe auch nicht erwartet, dass du die Frage verstehst.

von Alex G. (dragongamer)


Lesenswert?

Echt jetzt, muss diese Überheblichkeit sein?
Bin Praktiker und kein Theoretiker den es interessiert die Sprache "zu 
verstehen". Dafür habe ich meine Bachelor Thesis mit Softwareprojekt in 
richtigem C++ geschrieben.

von W.S. (Gast)


Lesenswert?

Alex G. schrieb:
> Echt jetzt, muss diese Überheblichkeit sein?

ist doch eigentlich nicht wichtig. Die Leute, die sich mit Rust befassen 
und es bewerben wollen, schaffen es ja nicht einmal, eine saubere 
Sprachdefinition hinzukriegen.
Siehe z.B. dort:
https://rust-lang-de.github.io/rustbook-de/

Da wird zuerst die Werbetrommel gerührt, was für hehre Ziele Rust denn 
so hat, Zitat: "Willkommen! Dieses Buch wird dir die Programmiersprache 
Rust beibringen. Rust ist eine Systemprogrammiersprache mit dem Fokus 
auf drei Ziele: Sicherheit, Geschwindigkeit und Nebenläufigkeit (Safety, 
Speed, Concurrency). Sie erreicht diese Ziele ohne Garbage Collector, 
was sie zu einer nützlichen Sprache für eine Reihe von Anwendungsfällen 
macht, in denen andere Sprachen nicht so gut sind..."

und dann kommt nicht das Allerwichtigste, nämlich eine Sprachdefinition 
(vorzugsweise Backus-Naur), sondern sowas: (wieder ein Zitat)

Erste Schritte - Richte deinen Computer ... ein.
Lerne Rust - Lerne Rust-Programmierung durch kleine Projekte.
Effektives Rust - Fortgeschrittene Konzepte, um ausgezeichneten 
Rust-Code zu schreiben.
Syntax und Semantik - Jedes Stück Rust auf kleine Stücke 
heruntergebrochen.
Nightly Rust - Cutting-edge features, die noch nicht im stabilen 
Compiler verfügbar sind.
Glossar - Erklärungen von Begriffen, die in diesem Buch verwendet 
werden.
Akademische Forschung - Literatur, die Rust beeinflusst hat.

Was soll das?
Das ist ja schlimmer als die Leute, die eurer Oma ne Wolldecke mit 
Magneten drin verhökern wollen.

Hier liegt ein Sprach-Gewurschtel vor und keine sauber konstruierte 
Programmiersprache. Die Fans fummeln an tausend kleinen Details herum, 
ohne daß es eine saubere logische Gesamtdefinition gäbe - und das macht 
eben keine gute Programmiersprache aus.

Und ihr wollt hier diskutieren, ob sich DAS als Programmiersprache für 
einen PIC32 oder einen Cortex eignet? Nur zu, wer es sich in den Kopf 
gesetzt hat, partout Rust für die Firmware seines BluePill-Brettl's oder 
seines AVR nehmen zu wollen, der muß es halt tun - wenngleich ich das 
Ganze für eine ausgemachte .. naja, sagen wir mal Theoretisiererei.. 
halte.

Ich bin mir sicher, daß in den nächten 10 Jahren weitere 30 derartige 
Sprachen der staunenden Fachwelt vorgestellt werden, die allesamt und 
jede für sich alles bisher Dagewesene in den Schatten stellt.

OK, um hier im Forum ein bissel zu diskutieren, mag Rust ja geeignet 
sein.

W.S.

von Alex G. (dragongamer)


Lesenswert?

Glaube du zählst zu den wenigen Personen welche sich beim Befassen mit 
einer neuen Sprache, als erstes die Backus Naur Form sehen wollen...

Btw. hat es mich nur eine Google Query gekostet, zu finden was du 
scheinbar suchst: https://doc.rust-lang.org/grammar.html


Dass immer wieder revolutionäre Sprachen auftauchen die sich nie so 
richtig durchsetzen ist leider wahr. Damit hat auch Rust zu kämpfen, 
denn die Millionen C Entwickler kriegt man schlicht nicht umgeschult. 
Trotzdem ist die Sprache sehr förderungswert - zu unser aller 
Sicherheit!


Beliebt ist die Sprache jedenfalls. Schon seit drei Jahren an der 
Spitze: 
https://insights.stackoverflow.com/survey/2018/#most-loved-dreaded-and-wanted

: Bearbeitet durch User
von Karl K. (karl2go)


Lesenswert?

Alex G. schrieb:
> Damit hat auch Rust zu kämpfen,
> denn die Millionen C Entwickler kriegt man schlicht nicht umgeschult.

Da kann man nur auf die Plancksche Lösung warten. Leider wachsen immer 
wieder welche nach...

Alex G. schrieb:
> Beliebt ist die Sprache jedenfalls. Schon seit drei Jahren an der
> Spitze:

Naja, Python steht da auch auf Platz drei, während Pascal nichtmal 
vorkommt. Beliebtheit ist offenbar kein Qualitätskriterium. ;-)

: Bearbeitet durch User
von Alex G. (dragongamer)


Lesenswert?

Gute Nutzbarkeit ist natürlich ausschlaggebend und da ist Python kaum 
geschlagen.

Klar, in der Umfrage da werden alle Entwickler-Arten von Embedded bis AI 
zusammengenommen.

Wobei Rust eigentlich auch nicht unbedingt in erster Linie für Embedded 
ist. Die aktuellen Vorzeigeprojekte sind im Bereich Server und Desktop.

von S. R. (svenska)


Lesenswert?

Alex G. schrieb:
> Beliebt ist die Sprache jedenfalls.

Wobei man hinzufügen sollte, dass Rust keine nennenswerte Verbreitung 
hat (unter 4.2% in der gleichen Umfrage, d.h. taucht unter den Top 25 
nicht auf). Daraus lässt sich schließen, dass die hohe Beliebtheit von 
einer kleinen, sehr loyalen Anhängerschaft stammt.

Im Technologiegraph taucht Rust ebenfalls nicht auf, vermutlich wird 
Rust zu selten professionell eingesetzt. Schade eigentlich, denn dort 
hätte man die Anwendungsfälle sehen können.

Nachtrag: Delphi/Object Pascal taucht in der Liste der unbeliebtesten 
Sprachen auf Platz 12 auf, gleich neben C. C++ steht auf beiden Listen, 
polarisiert also offensichtlich sehr stark.

Überhaupt finde ich die Liste der beliebtesten Sprachen interessant.

: Bearbeitet durch User
von Alex G. (dragongamer)


Lesenswert?

S. R. schrieb:
> Alex G. schrieb:
>> Beliebt ist die Sprache jedenfalls.
>
> Wobei man hinzufügen sollte, dass Rust keine nennenswerte Verbreitung
> hat (unter 4.2% in der gleichen Umfrage, d.h. taucht unter den Top 25
> nicht auf). Daraus lässt sich schließen, dass die hohe Beliebtheit von
> einer kleinen, sehr loyalen Anhängerschaft stammt.
Würde eher sagen die Beliebtheit stammt von Leuten die von der Sprache 
gehört haben und sie "interessant" finden, aber sie trotzdem nicht 
selber einsetzen (im Privaten hat man selten Projekte wo die Sprache 
Sinn macht und professionell ist sie leider eher rar wie du schon 
sagst).
Die Umfrage betrachtet nicht nur die tatsächlichen Nutzer der Sprache.

> Im Technologiegraph taucht Rust ebenfalls nicht auf, vermutlich wird
> Rust zu selten professionell eingesetzt. Schade eigentlich, denn dort
> hätte man die Anwendungsfälle sehen können.
Leider wahr.
Der englische Wiki Artikel nennt ein paar Programme bzw. Projekte welche 
die Sprache einsetzen. Zwei davon sind allerdings von Mozilla selbst.


> Überhaupt finde ich die Liste der beliebtesten Sprachen interessant.
Was haben eigentlich alle gegen Visual Basic? o.O

: Bearbeitet durch User
von S. R. (svenska)


Lesenswert?

Alex G. schrieb:
> Die Umfrage betrachtet nicht nur die tatsächlichen Nutzer der Sprache.

Ich glaube, dass Rust hauptsächlich von Leuten angekreuzt wird, die es 
auch nutzen. Sonst hat ja niemand dazu einen Grund (bzw. wenn ich mich 
recht entsinne, stand das auch dabei). Und da es kaum professionelle 
Projekte in Rust gibt, sind das alles Hobbyisten - und die würden kein 
Rust verwenden, wenn sie es nicht toll fänden.

Alex G. schrieb:
>> Überhaupt finde ich die Liste der beliebtesten Sprachen interessant.
> Was haben eigentlich alle gegen Visual Basic? o.O

Naja, ich hab damit (und QBasic) angefangen, vor ziemlich vielen Jahren. 
Letztes Jahr habe ich aus nostalgischen Gründen (und weil ich bei meinen 
Eltern war) mal mein altes, dickes Fachbuch* rausgekramt und mich 
speziell in die Details reingelesen, die ich als Kind damals nicht 
verstanden habe.

*konkret "Visual Basic 6 Kompendium" von Peter Monadjemi

Nee, ich hab nicht das Gefühl bekommen, nochmal mit VB6 arbeiten zu 
wollen.

von Kaj (Gast)


Lesenswert?

Alex G. schrieb:
> Wobei Rust eigentlich auch nicht unbedingt in erster Linie für Embedded
> ist.
Das ist richtig, aber gerade da koennte Rust, m.M.n., punkten. Besonders 
da, wo hohe Anforderungen an Fehlerfreiheit gestellt werden. Da man 
viele Fehler in Rust, verglichen mit C und C++, gar nicht erst machen 
kann, beschraenken sich die Fehler fast ausschliesslich auf Logikfehler.

Alex G. schrieb:
> und professionell ist sie leider eher rar wie du schon sagst
Sehe ich nicht so. Siehe hier:
https://www.rust-lang.org/en-US/friends.html

Mit Cloudflare, Dropbox, Threema, Mozilla (die es ja entwickelt haben), 
Samsung, etc. sind schon ein paar grosse/bekannte Namen dabei, die Rust 
aktiv nutzen.

Und auch dieses 5 Seiten PDF, wie Rust bei einem Spielestudio seine 
Vorteile ausspielt, finde ich sehr interessant:

Rust Case Study:
Chucklefish Taps Rust to Bring Safe Concurrency to Video Games
https://www.rust-lang.org/pdfs/Rust-Chucklefish-Whitepaper.pdf

Es gibt praktisch kaum einen Grund, nicht auf Rust zu setzten (ausser im 
Embedded Bereich, wobei ARM schon recht gut unterstuetzt wird). Das 
Oekosystem ist sehr durchdacht, man muss keine Angst haben, dass man 
z.B. eine bestimmte Version eines Crates nicht mehr bekommt (ausser 
Github explodiert), man muss sich Abhaengigkeiten nicht von Hand 
zusammensuchen, etc.

Zum veroeffentlichen eines Crates braucht man zwar einen GitHub-Account, 
aber den Code selbst kann man Hosten wo man will.

Auch das Unittesting finde ich sehr gut, da man praktisch alle 
Funktionen testen kann, was in C++ mit privaten Methoden schon schwer 
wird. Auch das Benchmarking finde ich klasse, wobei das, je nach 
Funktion, etwas tricky werden kann.

Insgesamt wirkt die Sprache und das gesamte Oekosystem sehr durchdacht. 
Ob die eigentliche Toolchain wirklich durchdacht ist, darueber koennte 
man bestimmt streiten. Gerade fuer den Embedded Bereich wuerde ich es 
schoener finden, wenn aus Rust nur Zwischencode erzeugt wird, den man 
dann an einen beliebigen Compiler z.B. an den AVR-GCC verfuettert. So 
schlage ich mich immernoch damit herum, avr-rust zu bauen, was praktisch 
immer an LLVM scheitert...

Aber gut, es ist wie es ist, und abgesehen von Embedded, bin ich mit 
Rust sehr zufrieden.

von Carl D. (jcw2)


Lesenswert?

Kaj schrieb:
> .... Gerade fuer den Embedded Bereich wuerde ich es
> schoener finden, wenn aus Rust nur Zwischencode erzeugt wird, den man
> dann an einen beliebigen Compiler z.B. an den AVR-GCC verfuettert. So
> schlage ich mich immernoch damit herum, avr-rust zu bauen, was praktisch
> immer an LLVM scheitert...

Es gibt ein C-Backend für LLVM, das genau für den Usecase gedacht ist.

rust -(rustc)-> C -(GCC)-> AVR8

Sicher nicht ideal, aber besser als nichts.

von Privatfrickler (Gast)


Lesenswert?

S. R. schrieb:
> Naja, ich hab damit (und QBasic) angefangen, vor ziemlich vielen Jahren.
> Letztes Jahr habe ich aus nostalgischen Gründen (und weil ich bei meinen
> Eltern war) mal mein altes, dickes Fachbuch* rausgekramt und mich
> speziell in die Details reingelesen, die ich als Kind damals nicht
> verstanden habe.

Dann sei froh, dass du damals nicht an Rust geraten bist. Denn mit so 
einer Einführung hier

https://rust-lang-de.github.io/rustbook-de/

Erst hüh

"Es ist ebenfalls beachtenswert, dass hier keine Typangaben notwendig 
waren: Obwohl Rust statisch typisiert ist, mussten wir den Typ nicht 
ausdrücklich angeben. Rust hat type inference [engl.: Typinferenz, 
Typableitung], um die Stärke statischer Typen und der Ausführlichkeit 
des Angebens von Typen auszubalancieren."

dann hott

"Anders als bei let, musst du die Typen von Funktionsargumenten angeben. 
Das hier funktioniert nicht:

# #![allow(unused_variables)]
#fn main() {
fn print_sum(x, y) {
    println!("sum is: {}", x + y);
}
"
Aha! Manchmal ist es eine Stärke von Rust KEINE Typangaben machen zu 
müssen und manchmal ist eine Stärke von Rust DOCH Typangaben machen zu 
müssen oder wie?

Der Autor bekennt und lobt in der "Wir" Form:

"Das ist eine bewusste Designentscheidung. Obwohl das Herleiten der 
Typen eines kompletten Programmes möglich ist, wie zum Beispiel in 
Sprachen wie Haskell, wird dennoch häufig dazu geraten die Typen 
ausdrücklich zu dokumentieren. Wir stimmen zu, dass ausdrückliche 
Typvermerke in Funktionssignaturen und Typherleitung innerhalb von 
Funktionskörpern wundervoller Mittelweg ist."

Dann solche Schwurbelsätze wie

"Referenzen interagieren mit dem ownership-System durch das ‚Ausleihen‘ 
(borrowing) dessen, worauf sie zeigen. Der Unterschied ist, dass sie 
nicht den zugrunde liegenden Speicher freigibt, wenn die Referenz den 
Scope verlässt. Falls sie das täte, dann würden wir zweimal freigeben, 
was schlecht wäre."

Der Abschnitt beginnt mit

"Referenzen interagieren mit dem ownership-System .."

Klingt für mich ähnlich wie

Der Programmierer interagiert mit seinem Quellcode
oder
Der Programmierer interagiert mit seinem Algorithmus so lange, bis der 
Mist endlich fehlerfrei läuft.

Dann heißt es
"push ist eine Methode auf Vektoren, die ein weiteres Element an das 
Ende des Vektors anhängt."

Mit Vektor soll hier das Stückchen String "Hallo Welt" gemeint sein. Aus

"let mut x = vec!["Hallo", "Welt"];"

Und was versteht der Autor unter einer Referenz y wenn er schreibt

"let y = &x[0];"

y sei nun das erste Element des Vektors x ?

doch nicht etwa

Erstes Element vec(x) = 'H'  ???

Warum wird eine schnöde Zeichenkette hier in Schwurbelpädagogik 
umschrieben, die nichts weiter als eine Ansammlung von Einzelelementen 
vom Typ Char ist, so aufgeplustert, als etwas völlig Artfremdes 
dargestellt, was es in anderen Sprachen doch schon seit umme gibt?

Dazu heißt es

"Wir haben eine weitere Variablenbindung y hinzugefügt. In diesem Fall 
ist y eine ‚Referenz‘ auf das erste Element des Vektors. Rusts 
Referenzen sind ähnlich wie Zeiger in anderen Sprachen, aber mit 
zusätzlichen Überprüfungen zur Kompilierzeit. Referenzen interagieren 
mit dem ownership-System durch das ‚Ausleihen‘ (borrowing) dessen, 
worauf sie zeigen."

Und? Hab ich jetzt mit

"let z = &x[1];"

mir hemmungslos das ZWEITE Element des Vektors x ausgeborgt?

Frau Gilzer, ich hätte gerne ein 'a'. Was muss ich da wohl tun?

Ach das ist einfach Herr Kandidat. Sie müssen lediglich per borrow sich 
eine Referenz von ihrem mutable-baren Vektor x ausleihen und dann einer 
neuen Variablen, z.B. z zuweisen, aber ohne mutable. Welches Element 
hättens denn gerne? Ach Frau Gilzer, geben Sie mir mal ein 'o'. Dann 
lieber Kandidat, wäre das so zu schreiben

"let z = &x[4];"

Nun haben Sie ein 'o' geborgt von ihrem Vektor x.

Aber lieber Kandidat, passen Sie auf, dass ihr x dabei nicht gerade den 
Scope verlässt. Sonst borgen Sie von etwas was ihnen gar nicht mehr 
gehört! Aber keine Sorge, da schreitet der Kompiler schon ein 
(hoffentlich). Bei uns fangen Sie sich jedenfalls keine Nebenläufigkeit 
ein. Das haben wir alles im Griff. Frau Gilzer, was ist denn eine 
Nebenläufigkeit? Ach Herr Kandidat, wenn ich ihnen das jetzt alles 
erklären müsste ...

Hauptsache Sie haben keinem hängenden Zeiger! Ich bitte Sie, Frau 
Gilzer! Bei mir hängt gar nix! Darauf können Sie sich verlassen.

Frau Gilzer: Und da wäre ja auch noch die iterator Invalidation. DIE ist 
erst speziell ...

von S. R. (svenska)


Lesenswert?

Privatfrickler schrieb:
> Dann sei froh, dass du damals nicht an Rust geraten bist.

Das wäre mir damals auch egal gewesen.
Verstanden hätte ich es sowieso nicht.

Ich hatte die "Visual Basic 6 Einsteiger Edition" und ein Buch von "DATA 
BECKER". Absolute Qualitätslektüre, ich weiß, aber für einen 
14-Jährigen, der sich da ganz allein ohne Hilfe durchboxen muss (bzw. 
will), sind solch bebilderte Anleitungen verdammt nützlich.

Habe ich damit "programmieren" gelernt? Sicherlich nicht.
Aber aus der Zeit stammt ein kleines Programm, was bei meinem Vater noch 
immer täglich im Einsatz ist. Und darauf bin ich ein kleines bisschen 
stolz. ;-)

von Privatfrickler (Gast)


Lesenswert?

S. R. schrieb:
> Privatfrickler schrieb:
>> Dann sei froh, dass du damals nicht an Rust geraten bist.
>
> Das wäre mir damals auch egal gewesen.
> Verstanden hätte ich es sowieso nicht.

Das meinte ich damit.

Da war PASCAL doch geradezu eine Wohltat gegen.

> Ich hatte die "Visual Basic 6 Einsteiger Edition" und ein Buch von "DATA
> BECKER". Absolute Qualitätslektüre,

Du wirst es nicht glauben, ich habe noch PC intern 4 - 
Systemprogrammierung. Ein fast 1400 Seiten Wälzer mit CD mit zig 
Assembler, C und PASCAL Listings. Kein schlechtes Buch!

> ich weiß, aber für einen
> 14-Jährigen, der sich da ganz allein ohne Hilfe durchboxen muss (bzw.
> will), sind solch bebilderte Anleitungen verdammt nützlich.
>
> Habe ich damit "programmieren" gelernt? Sicherlich nicht.
> Aber aus der Zeit stammt ein kleines Programm, was bei meinem Vater noch
> immer täglich im Einsatz ist. Und darauf bin ich ein kleines bisschen
> stolz. ;-)

Mit GFA BASIC auf dem AMIGA hab ich damals viele kleinere Progrämmchen 
geschafft. GFA BASIC fand ich damals schon sehr angenehm. Ich meine aus 
der Erinnerung, es ließ sich sogar kompilieren und lief dann flott.

von Privatfrickler (Gast)


Lesenswert?

PC intern 4 - Systemprogrammierung war ein DATA Becker Buch vom Autor 
Michael Tischer Erstauflage 1994.

von Privatfrickler (Gast)


Lesenswert?

S. R. schrieb:
> Ich hatte die "Visual Basic 6 Einsteiger Edition" und ein Buch von "DATA
> BECKER". Absolute Qualitätslektüre, ich weiß, aber für einen
> 14-Jährigen, der sich da ganz allein ohne Hilfe durchboxen muss (bzw.
> will), sind solch bebilderte Anleitungen verdammt nützlich.
>
> Habe ich damit "programmieren" gelernt? Sicherlich nicht.

Gerade nochmal recherchiert. Data Becker musste 2014 dicht machen.

https://www.heise.de/newsticker/meldung/Data-Becker-wird-geschlossen-1975472.html

Hier Jürgen Kuri dazu
https://plus.google.com/+J%C3%BCrgenKuri/posts/BCszMPpX9RS

von W.S. (Gast)


Lesenswert?

Alex G. schrieb:
> Glaube du zählst zu den wenigen Personen welche sich beim Befassen mit
> einer neuen Sprache, als erstes die Backus Naur Form sehen wollen...
>
> Btw. hat es mich nur eine Google Query gekostet, zu finden was du
> scheinbar suchst

Du hast den Sinn nicht erfasst.

Wenn ich unbedingt wollte, könnte ich mich selber auf die Suche machen, 
aber hier geht es nicht darum, was ich will, sondern darum, was die 
Rust-Leute ihren eventuellen Interessenten anbieten, also wie sich Rust 
dem Publikum präsentiert.

Da wäre eine straffe Definition der Sprache - eben per BNF - an 
allererster Stelle extrem hilfreich, um eine neue Sprache sachgerecht 
einzuführen und sie auf saubere Logik (oder eben deren Fehlen) 
abzuklopfen.

Was man dort jedoch sieht, ist Gelaber und Geschwurbel. Die PR-Leute von 
Rust schaffen es nicht, dem Leser einen sachlichen Überblick zu geben 
(weil sie den wohl selber nicht haben) und stochern stattdessen in 
Details herum.

Nochmal: die Sprache per BNF darzustellen ist ein Prüfstein für die 
Sprache selbst. Dort kommt es nämlich ganz schnell heraus, wenn es an 
innerer Logik fehlt und stattdessen mit Sonderfällen und "hier ist das 
eben so" gearbeitet wird.

W.S.

von Alex G. (dragongamer)


Lesenswert?

Denke schon die Tatsache dass es Rust Belt gibt zeigt dass es nicht 
grade schlecht um die Logik steht.
Und nochmal, für diese Sache interessieren sich theoretische 
Informatiker, aber kaum Programmierer und letztere sind es die Rust 
braucht und anlocken muss um erfolgreich zu sein!

Btw. wenn ich auf Java.com gehe finde ich sowas dazu auch nicht.
Was ist die Referenzseite zu C oder C++ wo die Theorie angeblich an 
erster Stelle steht?

: Bearbeitet durch User
Beitrag #5517631 wurde von einem Moderator gelöscht.
von Alex G. (dragongamer)


Lesenswert?

Nichteinmal die Logik Sprache schlechthin, Matlab stellt die Grammatik 
in ihrer Doku an erster Stelle!
https://de.mathworks.com/help/matlab/

: Wiederhergestellt durch Moderator
von Karl K. (karl2go)


Lesenswert?

S. R. schrieb:
> Ich hatte die "Visual Basic 6 Einsteiger Edition" und ein Buch von "DATA
> BECKER".

Siehste, andere hatten nur "Programmieren mit dem Mikrocomputer KC85" 
oder so. Das war aber nur ein dünnes Heftchen. Aber es kam ganz viel 
GOTO darin vor. ;-)

von Karl K. (karl2go)


Lesenswert?

W.S. schrieb:
> Da wäre eine straffe Definition der Sprache - eben per BNF - an
> allererster Stelle extrem hilfreich

Bei allem Geschwurbel, was Du hier abgibst, aber: Das fehlt mir bisher 
auch, um mal einen Überblick über die Sprache zu bekommen.

von S. R. (svenska)


Lesenswert?

Karl K. schrieb:
> Siehste, andere hatten nur "Programmieren mit dem Mikrocomputer KC85"
> oder so.

Och, auf dem hab ich auch ein bisschen BASIC gemacht.
Hauptsächlich aber DIGGER gespielt. :-)

Das war aber alles lange nach der Wende, die Bücher existieren schon 
lange nicht mehr und die KCs sind mit dem Tod der Station Junger 
Techniker alle entsorgt worden. Leider, ich hätte gerne einen davon 
gehabt.

von Alex G. (dragongamer)


Lesenswert?

Karl K. schrieb:
> W.S. schrieb:
>> Da wäre eine straffe Definition der Sprache - eben per BNF - an
>> allererster Stelle extrem hilfreich
>
> Bei allem Geschwurbel, was Du hier abgibst, aber: Das fehlt mir bisher
> auch, um mal einen Überblick über die Sprache zu bekommen.

Ehrlich gesagt halte ich es persönlich anhand meiner Erfahrungen aus dem 
Grundstudium, für nahezu unmöglich daraus einnechtes Gefühl dafür zu 
bekommen wie man mit der Sprache tatsächlich programmiert und ist es 
nicht das was zählt?

Es gab eine Reihe von Versuchen hochsichere Sprachen mathematisch zu 
bauen. Die sahen in solchen normierten Formen auch sehr schön aus. Den 
Bekanntheitsgrad von Rust konnte davon aber nichts erlangen weil sie 
einfach nicht wirklich praxistauglich sind.

Wie auch immer - enthält dieser Link nicht die Information die du 
brauchst?
https://doc.rust-lang.org/grammar.html

: Bearbeitet durch User
von S. R. (svenska)


Lesenswert?

Alex G. schrieb:
> Btw. wenn ich auf Java.com gehe finde ich sowas dazu auch nicht.
> Was ist die Referenzseite zu C oder C++ wo die Theorie angeblich an
> erster Stelle steht?

Du missverstehst da etwas absichtlich.

Erstens sind C, C++ und Java etablierte Sprachen, die müssen sich mit 
anderen Sprachen nicht mehr messen lassen. Deren Vor- und Nachteile sind 
bekannt.

Zweitens sind all diese Sprachen in einer Zeit entstanden, als eine 
vollständige, lückenlose Definition nicht notwendig war. Daraus folgen 
ziemlich hässliche Altlasten und komplexe formale Definitionen.

Neue Sprachen müssen mehr Anforderungen erfüllen als alte Sprachen, denn 
die Welt hat sich geändert. Sonderlocken im Parser drehen zu müssen ist 
nicht mehr akzeptabel, eine klare BNF macht das deutlich. 
Nebenläufigkeit und Speichermodelle sind ordentlich und klar in einer 
Weise zu definieren, die effiziente Implementationen ermöglicht. 
Undefiniertes Verhalten ist inakzeptabel.

Wenn man das hinkriegt, dann kann man seine Nische gründlich besetzen. 
Kotlin hat das für Android bereits getan. Rust nicht.

Btw: https://kotlinlang.org/docs/reference/grammar.html

von Alex G. (dragongamer)


Lesenswert?

Nagut, wenn du meinst dass die potentielle Nutzerschaft wirklich darauf 
achtet bzw. sich das durchlesen würde...

EDIT: Willst du mich verarschen oder so?
Dein Kotlin hat "grammar" exakt genau so wenig an erster Stelle der Doku 
wie Rust!

: Bearbeitet durch User
von S. R. (svenska)


Lesenswert?

Alex G. schrieb:
> EDIT: Willst du mich verarschen oder so?

Nein, ich habe zum Vergleich auf die BNF von Kotlin verlinkt. Da sind 
keine FIXMEs und längliche Erläuterungen drin.

Wenn du aber so angepisst reagierst, naja... schlaf dich erstmal aus.

: Bearbeitet durch User
von Privatfrickler (Gast)


Lesenswert?

Ich pick mir mal noch einen Absatz aus dem rustbook heraus.

https://rust-lang-de.github.io/rustbook-de/Variablenbindung.html

"Fast jedes nicht-triviale Rust-Programm verwendet Variablenbindungen. 
Sie sehen so aus:

fn main() {
    let x = 5;
}

fn main() { in jedes Beispiel zu schreiben ist ein wenig mühsam, also 
werden wir es in Zukunft weglassen. Falls du diese Beispiele 
ausprobierst, stelle sicher, dass du deinen Code in einer main() Methode 
schreibst (und nicht wie wir weglässt). Ansonsten bekommst du einen 
Fehler.

In vielen Sprachen wird das eine Variable genannt, aber Rusts 
Variablenbindungen haben ein paar Tricks im Ärmel. Zum Beispiel ist die 
linke Seite der let Anweisung ein ‘Muster’ und nicht einfach nur ein 
Variablenname. Das bedeutet, dass wir solche Sachen tun können:

# #![allow(unused_variables)]
#fn main() {
let (x, y) = (1, 2);
"

Was um alles in der Welt denkt sich dieser Schreiberling hier bei seinen 
Ausführungen?

Anstatt mal den Begriff "Variablenbindung" vor dessen Verwendung zu 
definieren, haut er mir gleich mal ein Beispiel um die Ohren, nämlich 
dieses hier

fn main() {
    let x = 5;
}

und geht anschließend überhaupt nicht mehr darauf ein. Statt dessen 
macht er einen auf "ich bin ein fauler Schreiber" und lässt gleich mal 
ein wichtiges Bestandteil zum NEULERNEN einer Programmiersprache weg. In 
C wäre das dann in etwa so:

Hier mal ein C-Programm für euch

printf("Hallo Welt")

Das Unwichtige mit dem main() und so hab ich mal weggelassen, weil ich 
(euer Tutor) bin ja schreibfaul (hihihi). Wenn ihr (Dooflinge) also mein 
Programm compilieren wollt, vergesst doch bitte nicht alles 
hinzuzufügen, was es bei einem ORDENTLICHEN C-Programm eben so braucht.

Da fällt mir wirklich die Hutkrempe herunter.

Dann der Halbsatz

"In vielen Sprachen wird das eine Variable genannt, ..."

" ... aber Rusts Variablenbindungen haben ein paar Tricks im Ärmel."

Was ist denn das für ein Schwafler, der so schreibt? Klingt als Leser 
wie "Hey! Hier is uns're supergoile Proggersprache mit den affengeilen 
Tricks im Ärmel"

Dann dieses tendenziöse "ich kann's euch nich erklären, darum bringe ich 
lieber ein Beispiel".

Da isses wieder:

"Zum Beispiel ist die linke Seite der let Anweisung ein ‘Muster’ und 
nicht einfach nur ein Variablenname. Das bedeutet, dass wir solche 
Sachen tun können:"

Jetzt müsste man ihn gleich löchern und fragen, erklären Sie doch mal 
genau, was ein Muster ist.

"Das bedeutet, dass wir solche Sachen tun können:"

Das bedeutet, DU lieber Schreiberling kannst NICHT erklären! DAS 
bedeutet das!

Das jenes hier

let x = 5;

so gar nicht ausschaut wie das Geklammerte hier (eben wegen dieser 
Klammern)

let (x, y) = (1, 2);

lässt er natürlich unter den Tisch fallen. Weil er das erste Beispiel 
unter den Tisch fallen lies und nix dazu erklärte. Vielleicht gab es 
auch gar nix dazu zu erklären, weil es einfach eine Variablendeklaration 
ist und sonst gar nix. Aber nein, er schrieb ja

"In vielen Sprachen wird das eine Variable genannt, "

legt den Schluss nahe, bei Rust ist das eben NICHT so oder vielleicht 
doch und der Autor weiß es einfach selber nicht so genau.

---

Und so gehen diese Erklärungen, d.h. dieses Geschwurbel weiter und 
weiter. Ich komm da keine paar Zeilen weit, ohne dass mir der 
Widerspruch in den Fingern juckt.

Vielleicht liegt es auch an diesem elendigen auf DU-und-DU gemache 
ICH-KENN-DICH-PERSÖNLICH Schreibstil, der immer öfter um sich greift, 
siehe

"Wenn du die zwei geschweiften Klammern ({}, manche nennen sie 
Schnurrbärte..) in deinem auszugebenden String einfügst, "

Sorry, aber ich möchte als Leser NICHT so angesprochen werden! Das stört 
mich auch oftmals an diesen YouTube-Vorträgen, in denen Studies gerne 
auf Kumpel machen, um mir was zu vermitteln. Gute Vorträge werden so 
nicht gesprochen. Dieser ASTA-Speech nervt mich total ab. Ich bekomme 
Wutstarre.

Korrekt heißt das so

Ein auszugebender String wird in geschweifte Klammern gesetzt.
Rust interpretiert die Klammern als Anweisung, an dieser Stelle einen 
Wert einzufügen.

Nix "wenn DU die" ... und "Schnurrbärte"

Dödel!

Beitrag #5517735 wurde von einem Moderator gelöscht.
Beitrag #5517752 wurde von einem Moderator gelöscht.
von Yalu X. (yalu) (Moderator)


Angehängte Dateien:

Lesenswert?

Alex G. schrieb:
> Karl K. schrieb:
>> W.S. schrieb:
>>> Da wäre eine straffe Definition der Sprache - eben per BNF - an
>>> allererster Stelle extrem hilfreich
>>
>> Bei allem Geschwurbel, was Du hier abgibst, aber: Das fehlt mir bisher
>> auch, um mal einen Überblick über die Sprache zu bekommen.
>
> Ehrlich gesagt halte ich es persönlich anhand meiner Erfahrungen aus dem
> Grundstudium, für nahezu unmöglich daraus einnechtes Gefühl dafür zu
> bekommen wie man mit der Sprache tatsächlich programmiert und ist es
> nicht das was zählt?

Mir geht es bzgl. der BNF ähnlich wie Alex:

Um mir einen ersten Eindruck über die Syntax einer Sprache zu
verschaffen, möchte ich ein paar aussagekräftige Codebeispiele und keine
formale Syntaxbeschreibung per BNF. Diese steht in Lehrbüchern – wenn
überhaupt vorhanden – üblicherweise ganz am Ende. Ich habe diese noch
nie komplett durchgelesen, sondern nutze sie allenfalls dann, wenn ich
eine konkrete Frage zu irgend einem syntaktischen Detail habe.

Um einen ersten Eindruck über die Semantik der Sprache zu bekommen,
möchte ich eine kurze Erläuterung der wichtigsten Eigenschaften in Prosa
und keine Semantikbeschreibung mittels abstrakter mathematischer
Modelle. Eine solche Beschreibung gibt es sowieso nur für die wenigsten
Programmiersprachen.

S. R. schrieb:
> Nein, ich habe zum Vergleich auf die BNF von Kotlin verlinkt. Da sind
> keine FIXMEs und längliche Erläuterungen drin.

Im Anhang findest du entsprechendes für Rust, ebenfalls ohne FIXMEs und
längliche Erläuterungen.

Beitrag #5517760 wurde von einem Moderator gelöscht.
Beitrag #5517761 wurde von einem Moderator gelöscht.
Beitrag #5517762 wurde von einem Moderator gelöscht.
Beitrag #5517763 wurde von einem Moderator gelöscht.
Beitrag #5517764 wurde von einem Moderator gelöscht.
Beitrag #5517765 wurde von einem Moderator gelöscht.
Beitrag #5517766 wurde von einem Moderator gelöscht.
Beitrag #5517767 wurde von einem Moderator gelöscht.
Beitrag #5517768 wurde von einem Moderator gelöscht.
Beitrag #5517771 wurde von einem Moderator gelöscht.
Beitrag #5517772 wurde von einem Moderator gelöscht.
Beitrag #5517773 wurde von einem Moderator gelöscht.
Beitrag #5517774 wurde von einem Moderator gelöscht.
Beitrag #5517778 wurde von einem Moderator gelöscht.
Beitrag #5517780 wurde von einem Moderator gelöscht.
Beitrag #5517782 wurde von einem Moderator gelöscht.
Beitrag #5517784 wurde von einem Moderator gelöscht.
Beitrag #5517785 wurde von einem Moderator gelöscht.
Beitrag #5517786 wurde von einem Moderator gelöscht.
Beitrag #5517787 wurde von einem Moderator gelöscht.
Beitrag #5517788 wurde von einem Moderator gelöscht.
Beitrag #5517789 wurde von einem Moderator gelöscht.
Beitrag #5517792 wurde von einem Moderator gelöscht.
Beitrag #5517794 wurde von einem Moderator gelöscht.
Beitrag #5517795 wurde von einem Moderator gelöscht.
Beitrag #5517799 wurde von einem Moderator gelöscht.
Beitrag #5517801 wurde von einem Moderator gelöscht.
Beitrag #5517804 wurde von einem Moderator gelöscht.
Beitrag #5517805 wurde von einem Moderator gelöscht.
Beitrag #5517806 wurde von einem Moderator gelöscht.
Beitrag #5517807 wurde von einem Moderator gelöscht.
Beitrag #5517808 wurde von einem Moderator gelöscht.
Beitrag #5517809 wurde von einem Moderator gelöscht.
Beitrag #5517810 wurde von einem Moderator gelöscht.
Beitrag #5517811 wurde von einem Moderator gelöscht.
Beitrag #5517813 wurde von einem Moderator gelöscht.
Beitrag #5517814 wurde von einem Moderator gelöscht.
Beitrag #5517815 wurde von einem Moderator gelöscht.
Beitrag #5517816 wurde von einem Moderator gelöscht.
Beitrag #5517817 wurde von einem Moderator gelöscht.
Beitrag #5517819 wurde von einem Moderator gelöscht.
Beitrag #5517820 wurde von einem Moderator gelöscht.
Beitrag #5517821 wurde von einem Moderator gelöscht.
von Yalu X. (yalu) (Moderator)


Lesenswert?

@privatfrickler:

Die deutsche Übersetzung des Rust-Handbuchs ist uralt. Nimm besser
dieses hier

  https://doc.rust-lang.org/book/2018-edition/

oder – falls dir das ebenfalls nicht zusagt – such dir eins von hier
aus, das besser deinem Geschmack entspricht:

  https://hackr.io/tutorials/learn-rust

Beitrag #5517823 wurde von einem Moderator gelöscht.
Beitrag #5517824 wurde von einem Moderator gelöscht.
Beitrag #5517825 wurde von einem Moderator gelöscht.
Beitrag #5517826 wurde von einem Moderator gelöscht.
Beitrag #5517827 wurde von einem Moderator gelöscht.
Beitrag #5517828 wurde von einem Moderator gelöscht.
Beitrag #5517829 wurde von einem Moderator gelöscht.
Beitrag #5517830 wurde von einem Moderator gelöscht.
Beitrag #5517831 wurde von einem Moderator gelöscht.
Beitrag #5517832 wurde von einem Moderator gelöscht.
Beitrag #5517833 wurde von einem Moderator gelöscht.
Beitrag #5517834 wurde von einem Moderator gelöscht.
Beitrag #5517836 wurde von einem Moderator gelöscht.
Beitrag #5517837 wurde von einem Moderator gelöscht.
Beitrag #5517838 wurde von einem Moderator gelöscht.
Beitrag #5517839 wurde von einem Moderator gelöscht.
Beitrag #5517840 wurde von einem Moderator gelöscht.
Beitrag #5517842 wurde von einem Moderator gelöscht.
Beitrag #5517843 wurde von einem Moderator gelöscht.
Beitrag #5517844 wurde von einem Moderator gelöscht.
Beitrag #5517845 wurde von einem Moderator gelöscht.
Beitrag #5517847 wurde von einem Moderator gelöscht.
Beitrag #5517848 wurde von einem Moderator gelöscht.
Beitrag #5517850 wurde von einem Moderator gelöscht.
Beitrag #5517851 wurde von einem Moderator gelöscht.
Beitrag #5517852 wurde von einem Moderator gelöscht.
Beitrag #5517853 wurde von einem Moderator gelöscht.
Beitrag #5517855 wurde von einem Moderator gelöscht.
Beitrag #5517857 wurde von einem Moderator gelöscht.
Beitrag #5517858 wurde von einem Moderator gelöscht.
Beitrag #5517859 wurde von einem Moderator gelöscht.
Beitrag #5517860 wurde von einem Moderator gelöscht.
Beitrag #5517862 wurde von einem Moderator gelöscht.
Beitrag #5517863 wurde von einem Moderator gelöscht.
Beitrag #5517864 wurde von einem Moderator gelöscht.
Beitrag #5517865 wurde von einem Moderator gelöscht.
Beitrag #5517867 wurde von einem Moderator gelöscht.
Beitrag #5517868 wurde von einem Moderator gelöscht.
Beitrag #5517869 wurde von einem Moderator gelöscht.
Beitrag #5517870 wurde von einem Moderator gelöscht.
Beitrag #5517871 wurde von einem Moderator gelöscht.
Beitrag #5517872 wurde von einem Moderator gelöscht.
Beitrag #5517873 wurde von einem Moderator gelöscht.
Beitrag #5517874 wurde von einem Moderator gelöscht.
Beitrag #5517875 wurde von einem Moderator gelöscht.
Beitrag #5517876 wurde von einem Moderator gelöscht.
Beitrag #5517877 wurde von einem Moderator gelöscht.
Beitrag #5517878 wurde von einem Moderator gelöscht.
Beitrag #5517880 wurde von einem Moderator gelöscht.
von Privatfrickler (Gast)


Lesenswert?

Yalu X. schrieb:
> @privatfrickler:
>
> Die deutsche Übersetzung des Rust-Handbuchs ist uralt. Nimm besser
> dieses hier
>
>   https://doc.rust-lang.org/book/2018-edition/
>
> oder – falls dir das ebenfalls nicht zusagt – such dir eins von hier
> aus, das besser deinem Geschmack entspricht:
>
>   https://hackr.io/tutorials/learn-rust

@Yalu

Danke für deinen Hinweis. Werde mir das mit etwas Abstand nochmals 
genauer betrachten. Ich bin gar nicht so extrem pingelig wie es 
vielleicht den Anschein weckt. Ich merke halt sehr schnell ob ein Text 
mich motiviert oder aber wie bei dem Geschwafel in mir das völlige 
Gegenteil bewirkt.

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Hallo,

Privatfrickler schrieb:

> "let y = &x[0];"
>
> y sei nun das erste Element des Vektors x ?

ja, aber viel weitreichender, als man sich so denkt? Denn, wenn ich das 
richtig sehe, kann man jetzt in x[0] nicht mehr schreiben?

vlg
 Timm

von Kaj (Gast)


Lesenswert?

Timm R. schrieb:
> ja, aber viel weitreichender, als man sich so denkt? Denn, wenn ich das
> richtig sehe, kann man jetzt in x[0] nicht mehr schreiben?
Es geht sogar noch weiter: Du kannst in keins der Elemente von x 
schreiben.
1
fn main() {
2
    let mut x = vec!["Hallo", "Welt"];
3
    let y = &x[0];
4
5
    x[0] = "Hello";
6
    x[1] = "World";
7
8
    println!("{:?}", x);
9
}
1
error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
2
 --> src/main.rs:5:5
3
  |
4
3 |     let y = &x[0];
5
  |              - immutable borrow occurs here
6
4 | 
7
5 |     x[0] = "Hello";
8
  |     ^ mutable borrow occurs here
9
...
10
9 | }
11
  | - immutable borrow ends here
12
13
error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
14
 --> src/main.rs:6:5
15
  |
16
3 |     let y = &x[0];
17
  |              - immutable borrow occurs here
18
...
19
6 |     x[1] = "World";
20
  |     ^ mutable borrow occurs here
21
...
22
9 | }
23
  | - immutable borrow ends here
24
25
error: aborting due to 2 previous errors
26
27
For more information about this error, try `rustc --explain E0502`.

Was du aber machen kannst: Mittels shadowing ein neues x anlegen.
1
fn main() {
2
    let mut x = vec!["Hallo", "Welt"];
3
    let y = &x[0];
4
5
    let mut x = vec!["Hello", x[1]];
6
7
    println!("{:?}", x);
8
}

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Hmm,

gut, in C++ kann man einen std::vector gar nicht mit einem structured 
binding verarzten, in sofern ...

Aber andererseits? Wegen einem Binding gleich das ganze Objekt 
blockieren?

Ich glaube, das gefällt mir nicht.

vlg

 Timm

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Hallo Alex,

Alex G. schrieb:
> Timm R. schrieb:
>> Könnte sich denn vielleicht einer der Rust-kundigen und C++-kundigen
>> erbarmen, mal ein minimales Beispiel mit c++ Pointer-Katastrophe zu
>> zeigen und wie es in Rust besser läuft? Das wäre doch sicher für mehrere
>> Rist-Unkundige interessant und erhellend? Mir fehlt da einfach die
>> Vorstellungskraft.
>
> Hmm, du hättest bei meinem Vortrag vor ein paar Wochen über Rust dabei
> sein sollen.
> Dafür habe ich den Heartbleed Bug in C++ nachprogrammiert - und dann
> versucht ihn auch unter Rust zu programmieren (ohne Unsafe).

also, erstmal danke für das instruktive Programm. Ja, das ist ein 
Beispiel für einen echten Sicherheitsgewinn. Ich möchte aber doch 
anmerken, m.h. tat das ja schon, wenn auch etwas stoffelig, dass das 
kein C++ ist.

Vielmehr wird ziemlich klar, dass auch in diesem Fall richtiges C++ das 
Problem schon gelöst hätte.

Yalus  Beispiel ist zwar valide. Aber auch da bin ich unschlüssig, ob 
den Tausch Brauchbarkeit der Features gegen eine bedingt relevante 
Sicherheit profitabel finde.

vlg

 Timm

von Alex G. (dragongamer)


Lesenswert?

Rust ist ganz klar einschränkend - bietet aber wiederum Strukturen um 
solche Einschränkungen ganz kontrolliert wieder aufzuheben.
Z.B. die CELL Datenstruktur.

Auch wenn ich hiermit meinen Realnamen preisgebe - hier habe ich einen 
Blogeintrag über Rust und RustBelt geschrieben: 
https://blog.mi.hdm-stuttgart.de/index.php/2018/07/23/rust-safety-during-and-after-programming/
Das enthält auch eine zusammenhängende Ausführung des Grundgedanken 
dieser Sprache mit Beispielen,

Beitrag #5518962 wurde von einem Moderator gelöscht.
Beitrag #5518963 wurde von einem Moderator gelöscht.
Beitrag #5518964 wurde von einem Moderator gelöscht.
Beitrag #5518966 wurde von einem Moderator gelöscht.
von Kaj (Gast)


Lesenswert?

Timm R. schrieb:
> Wegen einem Binding gleich das ganze Objekt
> blockieren?
>
> Ich glaube, das gefällt mir nicht.
Es ist ja nicht (vollstaendig) blockiert. Lesen kannst du noch ohne 
Probleme.
1
fn main() {
2
    let mut x = vec!["Hallo", "Welt"];
3
    let y = &x[0];
4
5
    println!("x: `{:?}`", x);
6
    println!("y: `{:?}`", y);
7
}
1
x: `["Hallo", "Welt"]`
2
y: `"Hallo"`

Ja, das Ownershipkonzept erfordert etwas umdenken, verglichen mit C und 
C++. Aber das Umdenken zahlt sich aus.

Beitrag #5518969 wurde von einem Moderator gelöscht.
Beitrag #5518970 wurde von einem Moderator gelöscht.
Beitrag #5518971 wurde von einem Moderator gelöscht.
Beitrag #5518973 wurde von einem Moderator gelöscht.
Beitrag #5518974 wurde von einem Moderator gelöscht.
Beitrag #5518975 wurde von einem Moderator gelöscht.
Beitrag #5518979 wurde von einem Moderator gelöscht.
Beitrag #5518980 wurde von einem Moderator gelöscht.
Beitrag #5518982 wurde von einem Moderator gelöscht.
Beitrag #5518988 wurde von einem Moderator gelöscht.
Beitrag #5518991 wurde von einem Moderator gelöscht.
Beitrag #5518994 wurde von einem Moderator gelöscht.
Beitrag #5518995 wurde von einem Moderator gelöscht.
Beitrag #5518996 wurde von einem Moderator gelöscht.
Beitrag #5518997 wurde von einem Moderator gelöscht.
Beitrag #5518998 wurde von einem Moderator gelöscht.
Beitrag #5518999 wurde von einem Moderator gelöscht.
Beitrag #5519000 wurde von einem Moderator gelöscht.
Beitrag #5519001 wurde von einem Moderator gelöscht.
Beitrag #5519003 wurde von einem Moderator gelöscht.
Beitrag #5519004 wurde von einem Moderator gelöscht.
Beitrag #5519005 wurde von einem Moderator gelöscht.
Beitrag #5519006 wurde von einem Moderator gelöscht.
Beitrag #5519007 wurde von einem Moderator gelöscht.
Beitrag #5519008 wurde von einem Moderator gelöscht.
Beitrag #5519009 wurde von einem Moderator gelöscht.
Beitrag #5519010 wurde von einem Moderator gelöscht.
Beitrag #5519011 wurde von einem Moderator gelöscht.
Beitrag #5519013 wurde von einem Moderator gelöscht.
Beitrag #5519014 wurde von einem Moderator gelöscht.
Beitrag #5519015 wurde von einem Moderator gelöscht.
Beitrag #5519016 wurde von einem Moderator gelöscht.
Beitrag #5519017 wurde von einem Moderator gelöscht.
Beitrag #5519018 wurde von einem Moderator gelöscht.
Beitrag #5519019 wurde von einem Moderator gelöscht.
Beitrag #5519020 wurde von einem Moderator gelöscht.
Beitrag #5519021 wurde von einem Moderator gelöscht.
Beitrag #5519022 wurde von einem Moderator gelöscht.
Beitrag #5519024 wurde von einem Moderator gelöscht.
Beitrag #5519026 wurde von einem Moderator gelöscht.
Beitrag #5519027 wurde von einem Moderator gelöscht.
Beitrag #5519029 wurde von einem Moderator gelöscht.
Beitrag #5519030 wurde von einem Moderator gelöscht.
Beitrag #5519031 wurde von einem Moderator gelöscht.
Beitrag #5519032 wurde von einem Moderator gelöscht.
Beitrag #5519033 wurde von einem Moderator gelöscht.
Beitrag #5519034 wurde von einem Moderator gelöscht.
Beitrag #5519035 wurde von einem Moderator gelöscht.
Beitrag #5519037 wurde von einem Moderator gelöscht.
Beitrag #5519039 wurde von einem Moderator gelöscht.
Beitrag #5519040 wurde von einem Moderator gelöscht.
Beitrag #5519041 wurde von einem Moderator gelöscht.
Beitrag #5519042 wurde von einem Moderator gelöscht.
Beitrag #5519046 wurde von einem Moderator gelöscht.
Beitrag #5519047 wurde von einem Moderator gelöscht.
Beitrag #5519048 wurde von einem Moderator gelöscht.
Beitrag #5519050 wurde von einem Moderator gelöscht.
Beitrag #5519051 wurde von einem Moderator gelöscht.
Beitrag #5519053 wurde von einem Moderator gelöscht.
Beitrag #5519054 wurde von einem Moderator gelöscht.
Beitrag #5519057 wurde von einem Moderator gelöscht.
Beitrag #5519059 wurde von einem Moderator gelöscht.
Beitrag #5519060 wurde von einem Moderator gelöscht.
Beitrag #5519061 wurde von einem Moderator gelöscht.
Beitrag #5519063 wurde von einem Moderator gelöscht.
Beitrag #5519065 wurde von einem Moderator gelöscht.
Beitrag #5519067 wurde von einem Moderator gelöscht.
Beitrag #5519069 wurde von einem Moderator gelöscht.
Beitrag #5519072 wurde von einem Moderator gelöscht.
Beitrag #5519073 wurde von einem Moderator gelöscht.
Beitrag #5519074 wurde von einem Moderator gelöscht.
Beitrag #5519075 wurde von einem Moderator gelöscht.
Beitrag #5519079 wurde von einem Moderator gelöscht.
Beitrag #5519080 wurde von einem Moderator gelöscht.
Beitrag #5519082 wurde von einem Moderator gelöscht.
Beitrag #5519083 wurde von einem Moderator gelöscht.
Beitrag #5519085 wurde von einem Moderator gelöscht.
Beitrag #5519086 wurde von einem Moderator gelöscht.
Beitrag #5519136 wurde von einem Moderator gelöscht.
Beitrag #5519137 wurde von einem Moderator gelöscht.
Beitrag #5519138 wurde von einem Moderator gelöscht.
Beitrag #5519139 wurde von einem Moderator gelöscht.
Beitrag #5519140 wurde von einem Moderator gelöscht.
Beitrag #5519142 wurde von einem Moderator gelöscht.
Beitrag #5519143 wurde von einem Moderator gelöscht.
Beitrag #5519144 wurde von einem Moderator gelöscht.
Beitrag #5519145 wurde von einem Moderator gelöscht.
Beitrag #5519146 wurde von einem Moderator gelöscht.
Beitrag #5519147 wurde von einem Moderator gelöscht.
Beitrag #5519148 wurde von einem Moderator gelöscht.
Beitrag #5519149 wurde von einem Moderator gelöscht.
Beitrag #5519150 wurde von einem Moderator gelöscht.
Beitrag #5519151 wurde von einem Moderator gelöscht.
Beitrag #5519152 wurde von einem Moderator gelöscht.
Beitrag #5519153 wurde von einem Moderator gelöscht.
Beitrag #5519155 wurde von einem Moderator gelöscht.
Beitrag #5519156 wurde von einem Moderator gelöscht.
Beitrag #5519157 wurde von einem Moderator gelöscht.
Beitrag #5519158 wurde von einem Moderator gelöscht.
Beitrag #5519159 wurde von einem Moderator gelöscht.
Beitrag #5519164 wurde von einem Moderator gelöscht.
Beitrag #5519165 wurde von einem Moderator gelöscht.
Beitrag #5519167 wurde von einem Moderator gelöscht.
Beitrag #5519168 wurde von einem Moderator gelöscht.
Beitrag #5519169 wurde von einem Moderator gelöscht.
Beitrag #5519170 wurde von einem Moderator gelöscht.
Beitrag #5519171 wurde von einem Moderator gelöscht.
Beitrag #5519172 wurde von einem Moderator gelöscht.
Beitrag #5519173 wurde von einem Moderator gelöscht.
Beitrag #5519174 wurde von einem Moderator gelöscht.
Beitrag #5519176 wurde von einem Moderator gelöscht.
Beitrag #5519177 wurde von einem Moderator gelöscht.
Beitrag #5519178 wurde von einem Moderator gelöscht.
Beitrag #5519179 wurde von einem Moderator gelöscht.
Beitrag #5519180 wurde von einem Moderator gelöscht.
Beitrag #5519181 wurde von einem Moderator gelöscht.
Beitrag #5519182 wurde von einem Moderator gelöscht.
Beitrag #5519184 wurde von einem Moderator gelöscht.
Beitrag #5519185 wurde von einem Moderator gelöscht.
Beitrag #5519186 wurde von einem Moderator gelöscht.
Beitrag #5519187 wurde von einem Moderator gelöscht.
Beitrag #5519189 wurde von einem Moderator gelöscht.
Beitrag #5519194 wurde von einem Moderator gelöscht.
Beitrag #5519203 wurde von einem Moderator gelöscht.
Beitrag #5519204 wurde von einem Moderator gelöscht.
Beitrag #5519205 wurde von einem Moderator gelöscht.
Beitrag #5519206 wurde von einem Moderator gelöscht.
Beitrag #5519207 wurde von einem Moderator gelöscht.
Beitrag #5519208 wurde von einem Moderator gelöscht.
Beitrag #5519209 wurde von einem Moderator gelöscht.
Beitrag #5519210 wurde von einem Moderator gelöscht.
Beitrag #5519211 wurde von einem Moderator gelöscht.
Beitrag #5519223 wurde von einem Moderator gelöscht.
Beitrag #5519224 wurde von einem Moderator gelöscht.
Beitrag #5519225 wurde von einem Moderator gelöscht.
Beitrag #5519226 wurde von einem Moderator gelöscht.
Beitrag #5519227 wurde von einem Moderator gelöscht.
Beitrag #5519231 wurde von einem Moderator gelöscht.
Beitrag #5519232 wurde von einem Moderator gelöscht.
Beitrag #5519233 wurde von einem Moderator gelöscht.
Beitrag #5519234 wurde von einem Moderator gelöscht.
Beitrag #5519235 wurde von einem Moderator gelöscht.
Beitrag #5519236 wurde von einem Moderator gelöscht.
von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

Kaj schrieb:
> Timm R. schrieb:
>> Wegen einem Binding gleich das ganze Objekt
>> blockieren?
>>
>> Ich glaube, das gefällt mir nicht.
> Es ist ja nicht (vollstaendig) blockiert. Lesen kannst du noch ohne
> Probleme.
Als weiterfuehrung zu meiner vorherigen Antwort:

Timm R. schrieb:
> gut, in C++ kann man einen std::vector gar nicht mit einem structured
> binding verarzten, in sofern ...
>
> Aber andererseits? Wegen einem Binding gleich das ganze Objekt
> blockieren?
>
> Ich glaube, das gefällt mir nicht.
Spiel einfach mal ein bisschen mit Rust. Theoretisch kannst du Rust 
'einfach' als C/C++ mit invertierten Regeln betrachten (grob gesagt).

==================================================

Beispiel 1, C/C++:
1
void foo(void)
2
{
3
    //...
4
}
Diese Funktion ist praktisch fuer jede andere Uebersetzungseinheit 
sichtbar, da sie nicht static ist (ja, es muss noch die .h-Datei 
eingebunden werden, ich weiss).

Beispiel 1, Rust:
1
fn foo() {
2
    //...
3
}
Diese Funktion ist nur innerhalb der Datei in der sie steht, sichtbar, 
da sie nicht explizit sichtbar gemacht wurde. Soll sie auch in anderen 
Uebersetzungseinheit sichtbar sein, dann muss das so aussehen:
1
pub fn foo() {
2
    //...
3
}

C und C++: Sichtbarkeit muss explizit eingeschraenkt werden.
Rust: Sichtbarkeit muss explizit ausgeweitet werden.

==================================================

Beispiel 2, C/C++:
1
int main(void)
2
{
3
    int a = 0;
4
    // ...
5
    return 0;
6
}
Die Variable a kann beschrieben werden, da sie nicht const ist.

Beispiel 2, Rust:
1
fn main()
2
{
3
    let a: i32 = 0;
4
    // ...
5
    return 0;
6
}
Die Variable a ist read-only (aber nicht const(!)), da sie nicht mut 
ist. Das heisst: man kann a mittels shadowing ueberdecken. Das geht bei 
einer Konstanten nicht.
1
fn main() {
2
    const A:i32 = 42;
3
    let A: i32 = 43;
4
}
5
6
error[E0005]: refutable pattern in local binding: `_` not covered
7
 --> src/main.rs:3:9
8
  |
9
3 |     let A: i32 = 43;
10
  |         ^ interpreted as a constant pattern, not new variable
1
fn main() {
2
    const A:i32 = 42;
3
    let mut A: i32 = 44;
4
}
5
6
error[E0530]: let bindings cannot shadow constants
7
 --> src/main.rs:3:13
8
  |
9
2 |     const A:i32 = 42;
10
  |     ----------------- a constant `A` is defined here
11
3 |     let mut A: i32 = 44;
12
  |             ^ cannot be named the same as a constant
C und C++: Schreibrechte muessen explizit entzogen werden.
Rust: Schreibrechte muessen explizit erteilt werden.

==================================================

Und so zieht es sich immer weiter. Wenn du es eben so betrachtest, dass 
Rust "nur ein invertiertes C/C++" ist, dann duerfte es dir leichter 
fallen die Sprache zu verstehen. So geht es zumindestens mir. Und genau 
durch diese 'Invertierung' erreicht Rust schon eine hoehere Sicherheit.

Gruesse

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Hallo Karl,

ja das ist soweit sehr interessant und hilfreich. Auch die Logik 
verstehe ich: der unaufmerksame Tipper tippt per default maximale 
Sicherheit.

Das gefällt mir auch sehr gut.

Borrowing als Alternative zu RAII erscheint mir allerdings wie die 
Therapie von Kopfschmerz durch Dekaputation. Da bin ich mir nicht 
sicher, ob das rockt.

Was ja sehr heiß sein soll ist die concurrency bei Rust. Vielleicht 
hilft da das Borrowing auch?

In c++ ist das Thema ja jetzt mit C++17 und später überhaupt erst auf 
dem Tapet.

Viele liebe Grüße

timm

von TriHexagon (Gast)


Lesenswert?

Timm R. schrieb:
> Was ja sehr heiß sein soll ist die concurrency bei Rust. Vielleicht
> hilft da das Borrowing auch?

Ja, das Ownership-System wurde eben wegen den Gefahren von nebenläufigen 
Code entworfen. In Rust ist es ebenso, dass ein Objekt entweder 
immutable ist, dann können mehrere darauf zugreifen, oder es ist mutable 
aber nur der Besitzer hat Schreibzugriff. Das Ownership-System 
garantiert das und deshalb können auch keine Raceconditions in Plain 
Rust auftreten. Natürlich lässt sich das mithilfe von unsafe umgehen, 
damit man trotzdem Semaphore und Co. in Rust umsetzen kann.

Durch das Ownership-System hat Rust definitiv ein nützliches 
Alleinstellungsmerkmal.

Beitrag #5519813 wurde von einem Moderator gelöscht.
Beitrag #5519814 wurde von einem Moderator gelöscht.
Beitrag #5519815 wurde von einem Moderator gelöscht.
Beitrag #5519817 wurde von einem Moderator gelöscht.
Beitrag #5519821 wurde von einem Moderator gelöscht.
Beitrag #5519823 wurde von einem Moderator gelöscht.
Beitrag #5519824 wurde von einem Moderator gelöscht.
Beitrag #5519870 wurde von einem Moderator gelöscht.
Beitrag #5519877 wurde von einem Moderator gelöscht.
Beitrag #5519894 wurde von einem Moderator gelöscht.
Beitrag #5519897 wurde von einem Moderator gelöscht.
von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

Timm R. schrieb:
> Was ja sehr heiß sein soll ist die concurrency bei Rust. Vielleicht
> hilft da das Borrowing auch?
Lies einfach mal hier:

Fearless Concurrency
https://doc.rust-lang.org/book/second-edition/ch16-00-concurrency.html

Using Threads to Run Code Simultaneously
https://doc.rust-lang.org/book/second-edition/ch16-01-threads.html

Using Message Passing to Transfer Data Between Threads
https://doc.rust-lang.org/book/second-edition/ch16-02-message-passing.html

Channels and Ownership Transference
https://doc.rust-lang.org/book/second-edition/ch16-02-message-passing.html#channels-and-ownership-transference
1
The ownership rules play a vital role in message sending because they
2
help you write safe, concurrent code. Preventing errors in concurrent
3
programming is the advantage of thinking about ownership throughout
4
your Rust programs.

von Bernd K. (prof7bit)


Lesenswert?

Kaj G. schrieb:
> Using Message Passing to Transfer Data Between Threads

Das ist übrigens ganz generell ein Entwurfsmuster das es auch in andern 
Sprachen sehr entspannt und angstfrei macht mit vielen Threads zu 
arbeiten ohne in die Bredouille zu kommen. Alles was man braucht ist 
eine threadsichere Queue.

: Bearbeitet durch User
Beitrag #5520001 wurde von einem Moderator gelöscht.
Beitrag #5520005 wurde von einem Moderator gelöscht.
Beitrag #5520006 wurde von einem Moderator gelöscht.
Beitrag #5520008 wurde von einem Moderator gelöscht.
von W.S. (Gast)


Lesenswert?

RalfW schrieb im Beitrag #5520008:
> Warum tut man sich das freiwillig an?

Einmal hätte doch gereicht.

Also, WARUM ?

Es ist vielen C-Programmierern seit geraumer Zeit klar, daß die Sprache 
C für die heutigen Bedürfnisse nicht mehr wirklich ausreicht und daß sie 
nicht mehr renovierungsfähig ist. Sie ist dafür bereits seit langem zu 
verkalkt.

Deshalb sinnieren viele C-Programmierer seit ebenso geraumer Zeit über 
neue Sprachentwürfe nach, mit denen sie all die uralten Geburtsfehler 
von C endlich hinter sich lassen können.

Dummerweise haben eben gerade die Programmierer, denen eine Nachfolge 
für C durchaus am Herzen liegt, "ihr" C so tief verinnerlicht, daß sie 
unfreiwillig bei jedem neuen Versuch einer neuen Programmiersprache 
sofort wieder in ihre eingefahrenen Denk-Gleise zurückfallen.

Deswegen kommt bei jeder neu erfundenen Programmiersprache im Grunde 
wieder nur C heraus, bloß hie und da mit irgendwelchen zusätzlichen 
Kringeln versehen, die die praktische Anwendung regelmäßig verhindern.

Kurzum, die Leute kommen einfach nicht aus ihrem Tunnelblick heraus, 
egal wie sie es anstellen.

Das ist das Tragische daran.

W.S.

: Wiederhergestellt durch Moderator
von Alex G. (dragongamer)


Lesenswert?

@W.S.
Du willst aber damit hoffentlich nicht ausdrücken dass das auch für Rust 
gelten würde, oder?

von TriHexagon (Gast)


Lesenswert?

W.S. schrieb:
> Deswegen kommt bei jeder neu erfundenen Programmiersprache im Grunde
> wieder nur C heraus, bloß hie und da mit irgendwelchen zusätzlichen
> Kringeln versehen, die die praktische Anwendung regelmäßig verhindern.

Mein Gott, wie kann man nur so wenig Ahnung haben und trotzdem so 
penetrant sein. Aber mach nur, mach dich weiter lächerlich, das steht 
dir so gut. ;)

Zu glauben Rust wäre wie C, weil es syntaktische Ähnlichkeiten hat, 
großartig. Das in etwa das Niveau von Moby...

von Karl K. (karl2go)


Lesenswert?

Alex G. schrieb:
> Du willst aber damit hoffentlich nicht ausdrücken dass das auch für Rust
> gelten würde, oder?

Doch, leider. Ist mir auch so ziemlich als erstes aufgefallen:

Diese unsäglichen geschweiften Klammern zum Einfassen einer Funktion 
oder Anweisung. Gleichzeitig benutzen sie es noch als Platzhalter.

Das C-typische = für Zuweisungen, == für Vergleiche. Ahhh. Nach zig 
Jahren if x = y sollte man es doch mal verstanden haben, dass das 
Bullshit ist.

Vielleicht könnte Rust das bessere C sein, aber es ist halt doch zuviel 
C.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Karl K. schrieb:
> Diese unsäglichen geschweiften Klammern zum Einfassen einer Funktion
> oder Anweisung. Gleichzeitig benutzen sie es noch als Platzhalter.

Siehe hier:

TriHexagon schrieb:
> Zu glauben Rust wäre wie C, weil es syntaktische Ähnlichkeiten hat,
> großartig. Das in etwa das Niveau von Moby...

Karl K. schrieb:
> Das C-typische = für Zuweisungen, == für Vergleiche. Ahhh. Nach zig
> Jahren if x = y sollte man es doch mal verstanden haben, dass das
> Bullshit ist.

Da ist in Python oder Haskell auch so. Ist deswegen Python==Haskell==C?

Nein. Und auch Rust ist – bis auf diese beiden minimalen syntaktischen
Ähnlichenkeiten – völlig verschieden von C.

von Bernd K. (prof7bit)


Lesenswert?

Karl K. schrieb:
> Nach zig
> Jahren if x = y sollte man es doch mal verstanden haben

Was faselst Du? Hast Du auch mal ausprobiert was Du da frech gelogen 
unterstellst oder schwallst Du einfach nur so aus Langeweile dumm daher 
damit irgendwas gesagt ist, ganz egal was?

von brackets (Gast)


Lesenswert?

Karl K. schrieb:
> Alex G. schrieb:
>> Du willst aber damit hoffentlich nicht ausdrücken dass das auch für Rust
>> gelten würde, oder?
>
> Doch, leider. Ist mir auch so ziemlich als erstes aufgefallen:
>
> Diese unsäglichen geschweiften Klammern zum Einfassen einer Funktion
> oder Anweisung. Gleichzeitig benutzen sie es noch als Platzhalter.
>
> Das C-typische = für Zuweisungen, == für Vergleiche. Ahhh. Nach zig
> Jahren if x = y sollte man es doch mal verstanden haben, dass das
> Bullshit ist.
>
> Vielleicht könnte Rust das bessere C sein, aber es ist halt doch zuviel
> C.

Bei der Zuweisung gebe ich dir recht, da wäre ein := besser. Aber immer 
noch besser als = == === in JavaScript ;-)
Die {} finde ich zum Einfassen von Blöcken nach wie vor besser leserlich 
als das unsägliche Einrücken in Python. Einmal die Quelle mit den 
falschen Einstellungen im Editor geladen und schon verhagelt es einem 
die Funktion des Programms. Da ist mir eine Sprache mit geschweiften 
Klammern lieber. Der Compiler weiß dann auch was zu tun ist, wenn 
irgendwelche Whitespaces durch andere ersetzt/optimiert wurden.
Auf Rust bin ich erst durch diesen Thread aufmerksam geworden und habe 
mich am Wochenende genauer damit beschäftigt. Bis jetzt finde ich die 
Sprache sehr interessant. Ich programmiere seit über 20 Jahren im 
embedded Bereich in C (nicht nur Projekte bei welchen zwei LEDs blinken 
;-)) und sehne mich nach einer Sprache, welche ähnlich für die 
Systemprogrammierung geeignet ist, mich vor Memory-Leaks, übergelaufenen 
Arrays etc. bewahrt, nativ und nicht in einer VM ausgeführt wird und 
keinen riesigen Overhead besitzt (z.B. Garbage Collector, fettes 
Exception-Handling ... hat hier schon jemand C++ unter den Rock geschaut 
... brrrr). Rust hat mich positiv überrascht, sogar Inline-Assembler ist 
möglich.

Gruß
{}

von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

W.S. schrieb:
> die die praktische Anwendung regelmäßig verhindern.
Dann zeig doch bitte die "Kringel" die die Anwendung von Rust 
verhindern.

W.S. schrieb:
> Kurzum, die Leute kommen einfach nicht aus ihrem Tunnelblick heraus,
> egal wie sie es anstellen.
Sagt ja der richtige...

Karl K. schrieb:
> Vielleicht könnte Rust das bessere C sein, aber es ist halt doch zuviel
> C.
Doof nur das Rust nicht viel mit C gemein hat, ausser etwas Syntax.

Karl K. schrieb:
> Das C-typische = für Zuweisungen, == für Vergleiche. Ahhh. Nach zig
> Jahren if x = y sollte man es doch mal verstanden haben, dass das
> Bullshit ist.
Auch du hast dich null mit Rust beschaeftigt.

1. Das was du da schreibst compiliert in Rust gar nicht.
1
fn main() {
2
    let mut x = 5;
3
    let mut y = 7;
4
5
    if x = y {
6
        // ...
7
    }
8
}
9
10
error[E0308]: mismatched types
11
 --> src/main.rs:5:8
12
  |
13
5 |     if x = y {
14
  |        ^^^^^
15
  |        |
16
  |        expected bool, found ()
17
  |        help: try comparing for equality: `x == y`
18
  |
19
  = note: expected type `bool`
20
             found type `()`

Wer glaubt, dass nur an den Typen von x und y liegt:
1
fn main() {
2
    let x = true;
3
    let y = false;
4
5
    if x = y {
6
        // ...
7
    }
8
}
9
10
error[E0308]: mismatched types
11
 --> src/main.rs:5:8
12
  |
13
5 |     if x = y {
14
  |        ^^^^^
15
  |        |
16
  |        expected bool, found ()
17
  |        help: try comparing for equality: `x == y`
18
  |
19
  = note: expected type `bool`
20
             found type `()`

Eine Zuweisung liefert keinen bool.

2. In Rust muessen alle Ausdruecke bei einem if ein bool liefern, und 
nicht etwas, das wie ein bool interpretiert werden koennte.
Was in C/C++ geht
1
if (x) {
2
3
}
compiliert in Rust ebefalls nicht
1
fn main() {
2
    let x = 5;
3
4
    if x {
5
        // ...
6
    }
7
}
8
9
error[E0308]: mismatched types
10
 --> src/main.rs:5:8
11
  |
12
5 |     if x {
13
  |        ^ expected bool, found integral variable
14
  |
15
  = note: expected type `bool`
16
             found type `{integer}`

Auch sowas geht nicht:
1
fn main() {
2
    let x = 5;
3
4
    if x & 5 {
5
        // ...
6
    }
7
}
8
9
error[E0308]: mismatched types
10
 --> src/main.rs:4:8
11
  |
12
4 |     if x & 5 {
13
  |        ^^^^^ expected bool, found integral variable
14
  |
15
  = note: expected type `bool`
16
             found type `{integer}`

Es compiliert erst, wenn ein bool rauskommt:
1
fn main() {
2
    let x = 5;
3
4
    if x & 5 == 5 {
5
        // ...
6
    }
7
}

Wenn man keine Ahnung hat...

von TriHexagon (Gast)


Lesenswert?

Karl K. schrieb:
> Diese unsäglichen geschweiften Klammern zum Einfassen einer Funktion
> oder Anweisung. Gleichzeitig benutzen sie es noch als Platzhalter.

Wo ist denn das Problem? Weil man statt geschweiften Klammern alles mit 
begin und end zu bombt? Ohne Syntax-Highlighting ist die Lesbarkeit mit 
begin/end allerdings schlecht. Passiert wenn man den Code mit cat oder 
diff ausgibt.

Karl K. schrieb:
> Das C-typische = für Zuweisungen, == für Vergleiche. Ahhh. Nach zig
> Jahren if x = y sollte man es doch mal verstanden haben, dass das
> Bullshit ist.

Ist kein Bullshit, weil man damit elegant gleichzeitig Zuweisen und 
Vergleichen kann. Gerade in Schleifenköpfe ist das praktisch.

Karl K. schrieb:
> Vielleicht könnte Rust das bessere C sein, aber es ist halt doch zuviel
> C.

Das ist reine Geschmacksache. Ich bevorzuge den Stil von C, aber 
deswegen Kotze ich mich bei VHDL doch nicht aus... . Daran bemisst sich 
ganz sicher nicht die Qualität von Rust, auch wenn es sich ein paar 
Ewiggestrigene wünschen, die immer noch um Pascal trauern.

von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

brackets schrieb:
> Aber immer
> noch besser als = == === in JavaScript ;-)
Das gibt es auch in PHP ;)

von TriHexagon (Gast)


Lesenswert?

TriHexagon schrieb:
> Karl K. schrieb:
>> Das C-typische = für Zuweisungen, == für Vergleiche. Ahhh. Nach zig
>> Jahren if x = y sollte man es doch mal verstanden haben, dass das
>> Bullshit ist.
>
> Ist kein Bullshit, weil man damit elegant gleichzeitig Zuweisen und
> Vergleichen kann. Gerade in Schleifenköpfe ist das praktisch.

Und das ist in Rust nicht einmal möglich, wie Kaj G. schon zeigte.

von Bernd K. (prof7bit)


Lesenswert?

x = y = z;

hätte auch keinen Sinn, selbst wenn es gehen würde wenn man bedenkt was 
der = Operator macht, je nachdem ob z copy ist oder nicht. Deshalb 
braucht keiner sowas wie das was da oben steht und käme auch nie auf die 
Idee sowas zu schreiben oder haben zu wollen.

Deshalb evaluiert eine Zuweisung immer zu (). Und () ist nicht bool.

Also hat Rust auch dieses Problem elegant über die Bande gespielt allein 
mit dem Typsystem nachhaltig aus der Welt geschafft ohne irgendwelche 
altgewohnte Syntax ändern zu müssen.

von Karl K. (karl2go)


Lesenswert?

Ja ok, ich sehe schon, Rust hat hier genauso arschlöchrige Fanboys wie 
C. Damit ist die Diskussion hinfällig.

von Zeno (Gast)


Lesenswert?

brackets schrieb:
> Die {} finde ich zum Einfassen von Blöcken nach wie vor besser leserlich
> als das unsägliche Einrücken in Python.

Wer sagt denn das es das Einrücken sein muß. Es gibt auch andere 
Möglichkeiten Blöcke zusammenzufassen bzw. zu kennzeichnen.
Es soll ja Programmiersprachen geben die den Anfang und das Ende eines 
Blockes im Klartext hinschreiben. Das empfinde ich als sehr angenehm, 
weil gut lesbar ist. Wenn dann noch dazu sinnvoll eingerückt wird ist es 
eigentlich optimal lesbar.
Ich kann auch mit der geschweiften Klammer leben - ist allemal besser 
als das Einrückungsprinzip in Python. Einen Vorteil hat allerdings das 
Pythonverfahren: Es zwingt zu einem sauberen Aufschreiben des 
Quelltextes.

von Rustbratwurst (Gast)


Lesenswert?

Warum zum Geier muss ich bei Rust immer an diesen komischen 
Kremelflieger denken? Bin ich etwa anders als andere?

von Zeno (Gast)


Lesenswert?

TriHexagon schrieb:
> weil man damit elegant gleichzeitig Zuweisen und
> Vergleichen kann. Gerade in Schleifenköpfe ist das praktisch.

Das ist eine ganz böse Falle, weil das auch mal richtig nach hinten los 
gehen kann.
Im Übrigen ist dieses Verhalten nicht vom verwendeten 
Zuweisungs-/Vergleichsoperator abhängig. Das könnte man mit jeder 
beliebigen Zuweisungs-/Vergleichsoperatorkombination realisieren, weil 
das letztendlich vom Compiler abhängt. Es hat aber schon gute Gründe, 
das es Compiler gibt die so etwas nicht zu lassen. Zuweisen ist halt 
etwas anderes als Vergleichen.

von TriHexagon (Gast)


Lesenswert?

Karl K. schrieb:
> Ja ok, ich sehe schon, Rust hat hier genauso arschlöchrige Fanboys wie
> C. Damit ist die Diskussion hinfällig.

Sich zuerst überheblich an solchen Kleinigkeiten aufhängen, dann sich 
eine blutige Nasse holen und gleich beleidigt abhauen. So ist recht.

Aber gut, eigentlich sollte es darum gar nicht gehen. Ich habe vor einem 
Jahr einen einfachen Assembler in Rust geschrieben. Und muss sagen, dass 
mir Rust sehr gut gefällt. Natürlich muss man sich ein bisschen mehr 
Gedanken durch das Ownership-System machen, man wird aber belohnt. Ich 
hatte allerdings noch nicht die Möglichkeit ein komplexeres Programm zu 
schreiben mit vielen Datenstrukturen. Da wäre interessant wie gut das 
geht.

Auch gefällt mir die Fehlerbehandlung in Rust durch nullable-Types mit 
Verzicht auf Exceptions. Durchs Patternmatching lässt sich das auch 
relativ elegant behandeln. Überhaupt sind diese mächtigen Enums wirklich 
genial.

Wollte mir in nächster Zeit mal mit Rust auf einem ARM Cortex 
beschäftigen, da sehe ich wirklich Potential.

von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

Was hier im Forum ja auch ganz gerne an C/C++ bemaengelt wird: die 
Endlosschleife.
In C/C++:
1
while (1) {
2
3
}
4
5
for (;;) {
6
7
}
Da wird ja auch gerne gemotzt, dass man das doch besser mit goto (oder 
sonst wie) machen sollte, weil alles andere ja eine zweckentfremdung der 
Schleife waere...

Auch das macht Rust ganz einfach:
1
loop {
2
3
}

Rust hat dazu auch noch Schleifen-Lables:
https://doc.rust-lang.org/rust-by-example/flow_control/loop/nested.html
1
#![allow(unreachable_code)]
2
3
fn main() {
4
    'outer: loop {
5
        println!("Entered the outer loop");
6
7
        'inner: loop {
8
            println!("Entered the inner loop");
9
10
            // This would break only the inner loop
11
            //break;
12
13
            // This breaks the outer loop
14
            break 'outer;
15
        }
16
17
        println!("This point will never be reached");
18
    }
19
20
    println!("Exited the outer loop");
21
}
Wie goto, nur deutlich weniger fehleranfaellig.

Was ich ebefalls schoen finde:
1
fn main() {
2
    let cond = true;
3
4
    let x = if cond {
5
        5
6
    } else {
7
        6
8
    };
9
}
In C/C++ muss man dazu x erstmal anlege und laesst es uninitialisiert 
oder belegt es erstmal mit einen dummy Wert, der dann wieder 
ueberschrieben werden muss.


Auf uninitialisierte Variablen kann in Rust nicht lesend zugegriffen 
werden:
1
fn main() {
2
    let x: i32;
3
    let y = x;
4
}
5
6
error[E0381]: use of possibly uninitialized variable: `x`
7
 --> src/main.rs:4:9
8
  |
9
4 |     let y = x;
10
  |         ^ use of possibly uninitialized `x`
Boom: Wieder ein typisches Problem von C und C++ einfach so aus dem Weg 
geraeumt.


Wer hier immernoch die Meinung vertritt, das Rust wie C ist, der moege 
doch bitte die Klappe halten. Ihr muesst es nicht nutzen, aber lasst uns 
doch unseren Spass an dieser Sprache. Nicht jeder moechte stehen 
bleiben, und Sprachen mit Konzepten (bzw. eher ohne Konzepten) von vor 
ueber 20 Jahren nutzen.

Rust unterstuetzt den Entwickler besser als die meisten anderen Sprachen 
(besonders besser als C und C++), um fehlerfreien/fehlerarmen Code zu 
schreiben. Und der Entwickler muss sich weniger Gedanken um Dinge wie 
undefined behavior machen, und kann sich mehr auf die eigentliche 
Aufgabe konzentrieren, ohne dabei auf die Performance von C/C++ 
verzichten zu muessen.

von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

TriHexagon schrieb:
> Ich
> hatte allerdings noch nicht die Möglichkeit ein komplexeres Programm zu
> schreiben mit vielen Datenstrukturen. Da wäre interessant wie gut das
> geht.
Wenn du ein grosses Projekt suchst, das in Rust geschrieben wird:
Sequoia-PGP
https://sequoia-pgp.org/

von TriHexagon (Gast)


Lesenswert?

Zeno schrieb:
> TriHexagon schrieb:
>> weil man damit elegant gleichzeitig Zuweisen und
>> Vergleichen kann. Gerade in Schleifenköpfe ist das praktisch.
>
> Das ist eine ganz böse Falle, weil das auch mal richtig nach hinten los
> gehen kann.
> Im Übrigen ist dieses Verhalten nicht vom verwendeten
> Zuweisungs-/Vergleichsoperator abhängig. Das könnte man mit jeder
> beliebigen Zuweisungs-/Vergleichsoperatorkombination realisieren, weil
> das letztendlich vom Compiler abhängt. Es hat aber schon gute Gründe,
> das es Compiler gibt die so etwas nicht zu lassen. Zuweisen ist halt
> etwas anderes als Vergleichen.

Da hast du recht und ich kann total verstehen, dass man das verbieten 
sollte. Aber die damalige Designentscheidung ist allerdings zumindest 
nachvollziehbar und kein "Bullshit", auch wenns zu einem weiteren 
Fallstrick führt.

von S. R. (svenska)


Lesenswert?

Karl K. schrieb:
> Ja ok, ich sehe schon, Rust hat hier genauso arschlöchrige
> Fanboys wie C. Damit ist die Diskussion hinfällig.

Welche Sprache wäre denn deiner Meinung nach ein würdiger Nachfolger von 
C? Jetzt sag aber bitte nicht C++ oder Assembler.

von Bernd K. (prof7bit)


Lesenswert?

Apropos Enums:

Option und Result, wer fühlt sich bei diesen beiden Enums nicht sofort 
an Haskell's Maybe und Either Monaden erinnert?

Auch das Auspacken in einem Pattern-Matching Konstrukt funktioniert 
genauso, ein Datentyp der mehrere "Formen" mit komplett 
unterschiedlichen Strukturen und Inhalten annehmen kann [wie ein union 
aber doch wieder irgendwie ganz anders, mächtiger und sicherer], zum 
Beispiel der Typ std::net::IpAddr ist ein Enum das entweder V4 oder V6 
sein kann und je nachdem komplett unterschiedliche Datenfelder hat, 
jedoch ist es vollkommen unmöglich Code zu schreiben der versehentlich 
auf die jeweils falschen Felder zugreift wenn man gerade ein Exemplar 
der einen oder der anderen Sorte vorliegen hat. Mit der selben Kraft des 
Enums kann man versehentliche Nullpointer-Dereferenzierung unmöglich 
machen.

Ich glaube die Enums wurden in diesem Thread noch nicht ausreichend 
gewürdigt, ich finde dieses Konzept mindestens genauso genial wie das 
Ownership-System (wenngleich es auch schon etwas älter ist und in 
anderen Sprachen ebenfalls vorkommt), allein die Enums und das 
Pattern-Matching machen die Sprache schon extrem mächtig und nützlich.

Irgendjemand hat auch mal Rust als Einstiegsdroge für Haskell 
bezeichnet, ich weiß zu wenig über Haskell um das kommentieren zu können 
aber mein Bauch sagt mir daß da zumindest teilweise was dran sein 
könnte.

: Bearbeitet durch User
von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Hallo Bernd,

schenk uns doch bitte mal ein MWE dazu, das wäre interessant(er).

vlg
 Timm

von Bernd K. (prof7bit)


Lesenswert?

Timm R. schrieb:
> schenk uns doch bitte mal ein MWE dazu, das wäre interessant(er).

Was ist ein "MWE"?

: Bearbeitet durch User
von mh (Gast)


Lesenswert?

S. R. schrieb:
> Welche Sprache wäre denn deiner Meinung nach ein würdiger Nachfolger von
> C? Jetzt sag aber bitte nicht C++ oder Assembler.

Wer sagt, dass c einen Nachfolger hat oder braucht? Und wenn es einen 
braucht, was spricht gegen c++?

Kaj G. schrieb:
> Wie goto, nur deutlich weniger fehleranfaellig.
Warum ist es weniger fehleranfällig? Wenn man goto nur in dieser 
Situation einsetzt, ist es das gleiche (das label steht an einer anderen 
Stelle).

Kaj G. schrieb:
> Was ich ebefalls schoen finde:fn main() {
1
     let cond = true;
2
 
3
     let x = if cond {
4
         5
5
     } else {
6
         6
7
     };
8
 }
> In C/C++ muss man dazu x erstmal anlege und laesst es uninitialisiert
> oder belegt es erstmal mit einen dummy Wert, der dann wieder
> ueberschrieben werden muss.
Ja, in einigen Fällen kann man so ohne uninitialisierte Variable 
auskommen, wo man sie in c++ nicht vermeiden kann. In den meisten Fällen 
kann man uninitialisierte Variablen aber leicht umgehen. Für dein 
Beispiel sieht das dann so aus:
1
auto x = 6;
2
if(cond) {
3
  x = 5;
4
}
Der Compiler erzeugt vermutlich identischen Code. Bei komplizierternen 
Fällen sollte man sich fragen, warum es so kompliziert ist und es 
vereinfachen.

Dein Beispiel ist meiner Meinung nach ziemlich schlecht lesbar. Eine 
Variablen wird über 5 Zeilen initialisiert. Ich muss 5 Zeilen lesen bis 
ich weiß, welchen Wert und Typ x hat. If als Ausdruck mit Wert, macht 
die Definition der Sprache vllt. einfacher und eleganter, aber für mich 
nicht leichter lesbar. Genauso unübersichtlich sind Funktionen mit 
Rückgabewert aber ohne return.

Kaj G. schrieb:
> Boom: Wieder ein typisches Problem von C und C++ einfach so aus dem Weg
> geraeumt.
Ich kann mich nicht daran erinnern, dass das für mich in c oder c++ im 
letzten Jahrzehnt ein Problem gewesen ist. Nachdem ich den Fehler ein 
paar mal gemacht habe, habe ich mir ganz schnell angewöhnt Variablen zu 
initialisieren und Klassen so du designen, dass sie nur initialisiert 
existieren können. Davon abgesehen warnt mich mein Compiler vor 
uninitialiserten Variablen (bzw die ide während ich tippe).
Kaj G. schrieb:
> use of possibly uninitialized `x`
Vor allem dieses "possibly" stört mich. Ich habe häufiger Variablen, bei 
denen der Compiler nicht wissen kann, ob sie initialisiert sind oder 
nicht. Und nein, es ist kein Sicherheitsrisiko, wenn man es sorgfältig 
macht.

von S. R. (svenska)


Lesenswert?

mh schrieb:
> Wer sagt, dass c einen Nachfolger hat oder braucht?
> Und wenn es einen braucht, was spricht gegen c++?

Vorweg: Ich programmiere gerne in C. Gleichzeitig sehe ich aber auch 
ein, dass C nicht der Weisheit letzter Schluss ist, aus wohlbekannten 
und bereits bekannten Gründen.

Meiner Meinung nach leider C++ an der gleichen Überkomplexität wie Perl: 
Es gibt zuviele Wege, ein Problem zu lösen. Das führt dazu, dass jeder 
sein persönliches Subset der Sprache benutzt, mit dem er Probleme gut 
lösen kann, aber am Ende beherrscht niemand die Sprache so gut, um die 
Lösungen anderer zuverlässig zu lesen (sprich: zu debuggen).

Und innerhalb dieser Diskussion hier habe ich nicht so richtig das 
Gefühl, dass Rust da wesentlich besser ist. Ich kann mich täuschen, habe 
aber gerade wenig Lust, mich in eine neue Sprache einzuarbeiten (im 
Augenblick arbeite ich ständig mit C++, Java, Kotlin, VHDL und hab den 
Kopf voll).

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Bernd K. schrieb:
> Timm R. schrieb:
>> schenk uns doch bitte mal ein MWE dazu, das wäre interessant(er).
>
> Was ist ein "MWE"?

Hey Bernd,

sorry! Minimal Working Example

vlg
 Timm

von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

Bernd K. schrieb:
> Option und Result, wer fühlt sich bei diesen beiden Enums nicht sofort
> an Haskell

https://doc.rust-lang.org/book/second-edition/ch06-00-enums.html
1
Enums are a feature in many languages, but their capabilities differ
2
in each language. Rust’s enums are most similar to algebraic data types
3
in functional languages, such as F#, OCaml, and Haskell.

Was ein valides struct ist, ist auch ein valides enum:
https://doc.rust-lang.org/rust-by-example/custom_types/enum.html
1
The enum keyword allows the creation of a type which may be one of a
2
few different variants. Any variant which is valid as a struct is also
3
valid as an enum.

mh schrieb:
> Warum ist es weniger fehleranfällig?
Weil du nicht irgendwo in der Funktion hinspringen kannst, sondern nur 
aus der Schleife raus. Nicht mehr und nicht weniger. Grosser Unterschied 
zu goto.

mh schrieb:
> Dein Beispiel ist meiner Meinung nach ziemlich schlecht lesbar. Eine
> Variablen wird über 5 Zeilen initialisiert.
Musst du ja nicht so machen. Kannst du ja genauso machen wie in C/C++:
1
fn main() {
2
    let cond = true;
3
    let mut x: i32 = 6;
4
5
    if cond {
6
        x = 5;
7
    }
8
}

Es gibt jetzt nur einen eklatanten unterschied:
In meinem Beispiel
1
let x = if cond {
2
    5
3
} else {
4
    6
5
};
ist x danach read-only, aber nicht const, d.h. x koennte per shadowing 
ueberdeckt werden, wenn man es braucht.

1
fn main() {
2
    let cond = true;
3
    let x = if cond {
4
        5
5
    } else {
6
        6
7
    };
8
9
    x = 7;
10
}
11
12
error[E0384]: cannot assign twice to immutable variable `x`
13
 --> src/main.rs:9:5
14
  |
15
3 |     let x = if cond {
16
  |         - first assignment to `x`
17
...
18
9 |     x = 7;
19
  |     ^^^^^ cannot assign twice to immutable variable
Soweit ich das sehe, ist sowas in C/C++ nicht moeglich.


mh schrieb:
> Ich kann mich nicht daran erinnern, dass das für mich in c oder c++ im
> letzten Jahrzehnt ein Problem gewesen ist.
Nur weil es fuer dich kein Problem ist, heisst das nicht, dass es kein 
generelles Problem ist. Schau nur mal wie viele Bugs es wegen nicht 
initialisierten Variablen (UB) gibt.

Bei meinem alten Arbeitgeber haben wir mal genau so einen Bug gesucht, 
der nur aufgefallen ist, weil unsere Software auf FreeBSD und auf 
Windows laufen musste. Auf BSD kein Problem, unter Windows hat sich das 
Programm aber anders verhalten. Was war das Problem?
1
bool flag;
2
3
// jede menge code
4
5
if (flag) {
6
7
} else {
8
9
}
Ist halt doof, wenn die Variable auf dem einen System Wert x und auf dem 
anderen Wert y hat.

Wenn es fuer dich kein Problem ist, ist ja gut, UB ist trotzdem mit 
einer der am verbreitesten Fehlerursachen in C/C++. Nullpointer, 
User-After-Free, etc. Alles UB.

mh schrieb:
> Und nein, es ist kein Sicherheitsrisiko, wenn man es sorgfältig
> macht.
Du sagst es ja selbst: Man muss extra aufpassen, weil genau sowas UB 
ist. Und gerade UB ist eben etwas, auf das ich in Rust nicht achten 
muss, und ich mir auch keinen Kopf darum machen will.

Kannst ja mal hier schauen, was so alles UB ist. Und dann sag mal, ob du 
das alles wusstest, und wenn nicht, ob du deine Programme jetzt danach 
durchsuchst und das behebst. ;)
Keine Angst, sind nur 203 Aufgelistet.
https://wiki.sei.cmu.edu/confluence/display/c/CC.+Undefined+Behavior

Und dazu kommt dann auch noch unspecified behavior. Auch das sind 'nur' 
58.
https://wiki.sei.cmu.edu/confluence/display/c/DD.+Unspecified+Behavior

Sind also gut 260 Fallstricke, die du immer im Kopf haben musst. Und das 
nur fuer C.
Man brauch ja nur mal hier im Forum suchen, wie es immer und immer 
wieder zu der Frage nach union kommt. Das endet nahezu immer darin, das 
man dem TO erklaeren muss, dass das was er da macht UB ist, und er es 
einfach ignoriert, weil es ja beim ihm funktioniert. 'Works for me!'
Kann also gar nicht falsch sein.

Sorry, aber damit gewinnt C und auch C++ keinen Blumentopf mehr.

von Carl D. (jcw2)


Lesenswert?

mh schrieb:
> Kaj G. schrieb:
.
>> Was ich ebefalls schoen finde:fn main() {
>
1
>      let cond = true;
2
> 
3
>      let x = if cond {
4
>          5
5
>      } else {
6
>          6
7
>      };
8
>  }
9
>
>> In C/C++ muss man dazu x erstmal anlege und laesst es uninitialisiert
>> oder belegt es erstmal mit einen dummy Wert, der dann wieder
>> ueberschrieben werden muss.
.
> Ja, in einigen Fällen kann man so ohne uninitialisierte Variable
> auskommen, wo man sie in c++ nicht vermeiden kann. In den meisten Fällen
> kann man uninitialisierte Variablen aber leicht umgehen. Für dein
> Beispiel sieht das dann so aus:
>
1
> auto x = 6;
2
> if(cond) {
3
>   x = 5;
4
> }
5
>
> Der Compiler erzeugt vermutlich identischen Code. Bei komplizierternen
> Fällen sollte man sich fragen, warum es so kompliziert ist und es
> vereinfachen.

Oder vielleicht schlicht die 1:1 Variante
1
auto x = (cond) ? 5 : 6;

von mh (Gast)


Lesenswert?

Kaj G. schrieb:
> Soweit ich das sehe, ist sowas in C/C++ nicht moeglich.
Wenn man es unbedingt braucht:
1
auto const x = cond ? 5 : 6;

Kaj G. schrieb:
> Du sagst es ja selbst: Man muss extra aufpassen, weil genau sowas UB
> ist. Und gerade UB ist eben etwas, auf das ich in Rust nicht achten
> muss, und ich mir auch keinen Kopf darum machen will.
Das bringt mir wenig, wenn ich statt dessen andauernd den Compiler 
"umgehen" muss, um meine Probleme zu Lösen (siehe: use of possibly 
uninitialized `x`).

Kaj G. schrieb:
> bool flag;
>
> // jede menge code
>
> if (flag) {
>
> } else {
>
> }
Bei rust nen Error bei c++ ne Warnung.


Kaj G. schrieb:
> Wenn es fuer dich kein Problem ist, ist ja gut, UB ist trotzdem mit
> einer der am verbreitesten Fehlerursachen in C/C++. Nullpointer,
> User-After-Free, etc. Alles UB.
Nullpointer und Use-After-Free sind keine wirklichen Probleme in c++, da 
man keine Raw-Pointer verwendet.

Kaj G. schrieb:
> Kannst ja mal hier schauen, was so alles UB ist.Und dann sag mal, ob du
> das alles wusstest, und wenn nicht, ob du deine Programme jetzt danach
> durchsuchst und das behebst.
Ich kenne nicht alle Fälle von UB, aber alle die relevant sind. Hast du 
die Liste gelesen?
1
A nonempty source file does not end in a new-line character which is not immediately preceded by a backslash character or ends in a partial preprocessing token or comment (5.1.1.2).
Sehr relevant... Wenn ich mich nicht irre hat gcc früher trotzdem 
gewarnt.
1
A program in a hosted environment does not define a function named main using one of the specified forms (5.1.2.2.1).
Kennt jemand einen Linker, der nicht meckert, wenn er kein main findet?
1
A reserved keyword token is used in translation phase 7 or 8 for some purpose other than as a keyword (6.4.1).
Muss ich davor Angst haben?

Kaj G. schrieb:
> Sorry, aber damit gewinnt C und auch C++ keinen Blumentopf mehr.
Wo findet man nochmal den vollständigen rust-Standard, in dem es kein 
Undefined Behaviour gibt? Die Antwort auf 
https://www.rust-lang.org/en-US/documentation.html:
> While Rust does not have a specification, the reference tries to describe
> its working in detail. It tends to be out of date.

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

mh schrieb:

Hallo,

> Kaj G. schrieb:
>> Wenn es fuer dich kein Problem ist, ist ja gut, UB ist trotzdem mit
>> einer der am verbreitesten Fehlerursachen in C/C++. Nullpointer,
>> User-After-Free, etc. Alles UB.
> Nullpointer und Use-After-Free sind keine wirklichen Probleme in c++, da
> man keine Raw-Pointer verwendet.

bzw, wenn man sie verwendet, dann sind das Fälle, wo auch in Rust 
"unsafe" stehen würde. Und eine Heap-Allokation die sich heimlich 
verabschiedet kann der Rust "unsafe" genau so wenig vorhersehen, wie ein 
C++ Compiler. Kein Unterschied.

Wobei man eben schon zugeben muss, dass sowas wie der C-Code oben aus 
dem Heartbleed Beispiel in Rust eben nicht so einfach einzuschmuggeln 
ist.



> Kaj G. schrieb:
>> Kannst ja mal hier schauen, was so alles UB ist.Und dann sag mal, ob du
>> das alles wusstest,

na, das ist doch mal etwas schräg? Ich kenne auch nicht alle Fraun, mit 
denen ich nicht verheiratet bin. Wozu denn auch? Du musst ein gutes 
Gebiet defined behavior kennen und das UB, dass dir auf die Füße fallen 
könnte, wenn du im Halbschlaf rumtipperst.

Kaj, du hast ja scheinbar einen riesen Fundus UB ausgegraben, dann nenn 
doch bitte mal ein einziges UB, das einen C++ Dilettanten wie mich 
überrascht, gern auch als Quizzfrage. Ich war noch nie von UB 
überrascht, sondern höchstens mal, dass etwas nicht UB ist, aber das ist 
ja nicht gefährlich.

vlg
 Timm

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Hallo,

nicht 100% ernst gemeint:

Vielleicht beginnt ja dann in Zukunft jeder noob sein Rust Programm mit
1
unsafe {

so wie in c++ das
1
using namespace std;

:-))

vlg
 Timm

von A. S. (Gast)


Lesenswert?

Kaj G. schrieb:
> bool flag;
>
> // jede menge code
>
> if (flag) {
>
> } else {

Da schlägt doch der Compiler Alarm, oder zumindest Lint. Ja, man kann in 
C so programmieren, dass solch Warnungen untergehen ...

von Privatfrickler (Gast)


Lesenswert?

Kaj G. schrieb:
> Bei meinem alten Arbeitgeber haben wir mal genau so einen Bug gesucht,
> der nur aufgefallen ist, weil unsere Software auf FreeBSD und auf
> Windows laufen musste. Auf BSD kein Problem, unter Windows hat sich das
> Programm aber anders verhalten. Was war das Problem?bool flag;
>
> // jede menge code
>
> if (flag) {
>
> } else {
>
> }

Selbst in Pelles C bekomme ich da bei un-initialisiertem Gebrauch von 
flag eine Warning geworfen!

C99 mit
1
<stdbool.h>
eingebunden
1
Building main.obj.
2
C:\Users\..\Documents\Pelles C Projects\bool01\main.c(22): warning #2229: Local 'flag' is potentially used without being initialized.
3
Done.

Beitrag #5520584 wurde von einem Moderator gelöscht.
Beitrag #5520585 wurde von einem Moderator gelöscht.
Beitrag #5520586 wurde von einem Moderator gelöscht.
Beitrag #5520587 wurde von einem Moderator gelöscht.
Beitrag #5520600 wurde von einem Moderator gelöscht.
Beitrag #5520601 wurde von einem Moderator gelöscht.
Beitrag #5520602 wurde von einem Moderator gelöscht.
Beitrag #5520603 wurde von einem Moderator gelöscht.
Beitrag #5520604 wurde von einem Moderator gelöscht.
Beitrag #5520605 wurde von einem Moderator gelöscht.
Beitrag #5520606 wurde von einem Moderator gelöscht.
Beitrag #5520607 wurde von einem Moderator gelöscht.
Beitrag #5520608 wurde von einem Moderator gelöscht.
Beitrag #5520609 wurde von einem Moderator gelöscht.
Beitrag #5520610 wurde von einem Moderator gelöscht.
Beitrag #5520612 wurde von einem Moderator gelöscht.
Beitrag #5520613 wurde von einem Moderator gelöscht.
Beitrag #5520614 wurde von einem Moderator gelöscht.
Beitrag #5520615 wurde von einem Moderator gelöscht.
Beitrag #5520617 wurde von einem Moderator gelöscht.
Beitrag #5520619 wurde von einem Moderator gelöscht.
Beitrag #5520620 wurde von einem Moderator gelöscht.
Beitrag #5520621 wurde von einem Moderator gelöscht.
Beitrag #5522113 wurde von einem Moderator gelöscht.
Beitrag #5522114 wurde von einem Moderator gelöscht.
Beitrag #5522143 wurde von einem Moderator gelöscht.
Beitrag #5522144 wurde von einem Moderator gelöscht.
Beitrag #5522145 wurde von einem Moderator gelöscht.
Beitrag #5522146 wurde von einem Moderator gelöscht.
von Operator S. (smkr)


Lesenswert?

@Kaj G.
Man kann sich die Beispiele auch so zurechtrücken, dass seine Ansichten 
am besten da stehen. So gerne ich Rust auch mag, so sind nicht all seine 
Eigenschaften ein Alleinstellungsmerkmal der Sprache.

Hier sagst du
Kaj G. schrieb:
> C und C++: Sichtbarkeit muss explizit eingeschraenkt werden.
> Rust: Sichtbarkeit muss explizit ausgeweitet werden.

merkst aber sogar selbst an, dass die Funktion über das Headerfile 
öffentlich gemacht werden muss. Noch expliziter gehts ja kaum.
Ausserdem sind in C++ Methoden in einer Klasse default private. 
Umgekehrt sind sie in einem struct default public.

Kaj G. schrieb:
> Auf uninitialisierte Variablen kann in Rust nicht lesend zugegriffen
> werden:
C++ initialisiert diese einem sogar, wenn man es nicht selber 
hinschreiben will.


Kaj G. schrieb:
> Was ich ebefalls schoen finde:fn main() {
>     let cond = true;
>
>     let x = if cond {
>         5
>     } else {
>         6
>     };
> }
> In C/C++ muss man dazu x erstmal anlege und laesst es uninitialisiert
> oder belegt es erstmal mit einen dummy Wert, der dann wieder
> ueberschrieben werden muss.
Die Behauptungen zu C++ stimmen schlichtweg nicht, was aber weiter oben 
schon erläutert wurde.

von Vincent H. (vinci)


Lesenswert?

Ich hab über Rust bisher leider nur gelesen und es selbst nie angewandt, 
aber was mir persönlich sehr abgehn würde und wofür es glaub ich bisher 
kein Äquivalent in C++ gibt ist:
- constexpr
- variadic arguments
- function overloading

Kann jemand dazu was sagen?
Grad constexpr wäre für eine embedded Sprache, in der es imho übermäßig 
viele compile-time Checks geben kann und sollte sehr wichtig.

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Hallo Vincent,

magst duu deinen Post noch mal lesen? Irgendwas stimmt da nicht.

Viele liebe Grüße
timm

: Bearbeitet durch User
von Vincent H. (vinci)


Lesenswert?

Err... zu meinte ich natürlich, Äquivalent zu C++, nicht in.

von Der wo ich bin (Gast)


Lesenswert?

Ich hab mal eine grundsätzliche Frage an die Community hier, welche ich 
mir jedesmal stelle, wenn Threads dieser Art (C vs. C++, C vs. Rust, C 
vs. Ada) aufploppen.

Wer würde folgenden Aussagen zustimmen?

Ich bevorzuge C gegenüber C++/Rust/Ada weil:

- diese Sprachen es zu leicht machen sich in eine Ecke zu designen.
- für ein Byte der Typ uint8_t genügt, es braucht keinen n-dimensionalen 
Bojackel-Schniepel aus den tiefen des Weltalls.
- ich keine Lust habe mich in die Abstraktionsuntiefen anderer zu 
begeben, wenn das Problem eigentlich einfacher zu lösen ist.

Ich persönlich habe mit Rust experimentiert, und wäre glücklich gewesen 
wenn es ein C mit borrow checker geworden wäre. Der Rest führt meiner 
Erfahrung nach, früher oder später, zu einer over engineering Kultur 
(wie bei allen Sprachen mit "mächtigem Typsystem"). Irgendwann kommt der 
Punkt an dem man sich zur akademisch niedrigsten Lebensform 
zurückentwickelt, dem Taxonomen 
(https://de.wikipedia.org/wiki/Taxonomie).

Aber wahrscheinlich abstrahiere ich nur gerne in die andere Richtung 
(uint8_t vs. Bojackel-Schniepel, denn hey, im Grunde sind alles nur 
Zahlen ;-) ).

P.S.:
Hat jemand Erfahrung mit https://ziglang.org?

von Bernd K. (prof7bit)


Lesenswert?

Der wo ich bin schrieb:
> für ein Byte der Typ uint8_t genügt, es braucht keinen n-dimensionalen
> Bojackel-Schniepel aus den tiefen des Weltalls.

Der Typ für einen "n-dimensionale Bojackel-Schniepel aus den tiefen des 
Weltalls als Ersatz für uint8_t" heißt in Rust ganz einfach u8.

Darüber hinaus sind Deine Aussagen über die negativen Eigenschaften von 
Rust etwas schwammig und nicht ganz nachvollziehbar. Insbesondere weil 
Du sagst der Borrow-Checker bereitet Dir erstaunlicherweise keine 
Probleme, das ist aber so ziemlich der komplizierteste Teil, alles 
andere ist genau wie C mit ein paar zusätzlichen Schmankerln (Enums, 
Pattern-Matching, etc.) und einer angenehmeren Syntax als C(++).

: Bearbeitet durch User
von Alex G. (dragongamer)


Lesenswert?

Der wo ich bin schrieb:
> Ich hab mal eine grundsätzliche Frage an die Community hier, welche ich
> mir jedesmal stelle, wenn Threads dieser Art (C vs. C++, C vs. Rust, C
> vs. Ada) aufploppen.
>
> Wer würde folgenden Aussagen zustimmen?
>
> Ich bevorzuge C gegenüber C++/Rust/Ada weil:
>
> - diese Sprachen es zu leicht machen sich in eine Ecke zu designen.
> - für ein Byte der Typ uint8_t genügt, es braucht keinen n-dimensionalen
> Bojackel-Schniepel aus den tiefen des Weltalls.
> - ich keine Lust habe mich in die Abstraktionsuntiefen anderer zu
> begeben, wenn das Problem eigentlich einfacher zu lösen ist.
Bei Entwicklern die nur ein paar tausendzeilige Programme schreiben 
wirst du ganz sicher Gleichgesinnte finden (Ausnahmen bestätigen die 
Regel).
Das setzt allerdings vorraus dass du eben Probleme hast die sich so 
einfach umsetzen lassen und vorallem vom Menschen (und einem späteren 
Leser des Codes) erfasst werden können. Schließlich ist das der 
Hauptgrundgrund für Abstraktion.

Wobei mein Argument hier wenig mit C vs Rust zutun hat, sondern mehr C 
vs Objektorientierung.
Dass es irgendwann ein "Rust++" mit vollwertiger Objektorientierung 
geben könnte sind Moment nur Gerüchte und Wünsche.

von S. R. (svenska)


Lesenswert?

Alex G. schrieb:
> Bei Entwicklern die nur ein paar tausendzeilige Programme schreiben
> wirst du ganz sicher Gleichgesinnte finden (Ausnahmen bestätigen die
> Regel).

Ein mächtiges Typsystem verleitet zu Missbrauch.

Wenn jede einzelne Information zu einem eigenen Datentyp gemacht wird, 
und durch die Abstraktionshierarchien hindurch ständig Datentypen 
ineinander konvertiert werden müssen (weil sie abstrakt definiert 
wurden, statt zueinander kompatibel), dann ist das jeglicher Form von 
Wartung abträglich. Und wenn man dann durch sechs, sieben 
Abstraktionsstufen hindurchgelaufen ist und eine Trivialität findet, 
dann fühlt man sich schon ein bisschen verarscht.

Komplexität taucht immer irgendwo auf, aber mir ist Komplexität in der 
Programmlogik (die man verfolgen kann) lieber, als Komplexität in der 
Abstraktionierung (eben weil man die nicht verfolgen kann - der Code ist 
über viele Dateien verstreut).

Aber das ist definitiv kein Fehler von Rust.

von Der wo ich bin (Gast)


Lesenswert?

Der borrow checker ist in der tat kein Problem. Das Problem ist das man 
(wie auch bei C++ und Ada) zum Taxonomen wird, wobei scheinbar immer 
versucht wird möglichst fein granulierte Designs und Typen zu 
implementieren. Nach Möglichkeit nah an der Realität, wobei ich mich da 
dann frage wo die Abstraktion sein soll. Ist dann eher eine 
Nachempfindung.

Mein Beispiel oben (uint8_t) z.B. wurde von Bernd K. falsch verstanden. 
Als ob ich nicht wüsste das es u8 gibt. Im Rust Forum hatte ich die 
Frage genau so auch gestellt (über die offizielle Webseite zu erreichen, 
Stichwort thinking in types). Antwort war "geht auch, aber idiomatisch 
müsstest du..."

Aber ich sehe wir haben einfach zu verschiedene Denkweisen.

P.S.:
Tausendzeilig? Die meisten Kernel und (bedeutenden) libs sind größer 
denke ich.

P.P.S.:
Ich schreibe nie mehr was per Telefon!

von Der wo ich bin (Gast)


Lesenswert?

An Alex G.:

Anstatt durch die Blume zu implizieren ich sei kein Profi, hätte keine 
Ahnung oder bin einfach zu dumm, google mal "Rust severely disappoints 
me" von Eric Raymond. Am besten auch googeln wer das ist.

Und kuck dir mal die Sprache Zig an und warum sie ins Leben gerufen 
wurde.
Zitat:
"Small, simple language. Focus on debugging your application rather than 
debugging your knowledge of your programming language."

Wahrscheinlich alle zu dumm, oder?

ein Zitat von L. Toralds, welches ich auf den Punkt gebracht finde:

"inefficient abstracted programming models where two years down the road
   you notice that some abstraction wasn't very efficient, but now all
   your code depends on all the nice object models around it, and you
   cannot fix it without rewriting your app."

von A. S. (Gast)


Lesenswert?

Der wo ich bin schrieb:
> Mein Beispiel oben (uint8_t)

Da ins gleiche Horn die 40 Jahre alte Weisheit: die von Mathematikern 
erfunden Zahlen sind kompakt und wunderschön. Sie sollten nicht von 
Ingenieuren zugemüllt werden.

Es ging darum, ob den Zahlen Einheiten zugeordnet sein sollten.  Nein! 
Auch wenn dann der Compiler  da ein paar Fallstricke erkennen kann ... 
Eine Zahl ist eine Zahl, wenn ich sie z.b. im Menü eingebe oder mit 
min/max teste...

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Achim S. schrieb:
> Der wo ich bin schrieb:
>> Mein Beispiel oben (uint8_t)
>
> Da ins gleiche Horn die 40 Jahre alte Weisheit: die von Mathematikern
> erfunden Zahlen sind kompakt und wunderschön. Sie sollten nicht von
> Ingenieuren zugemüllt werden.
>
> Es ging darum, ob den Zahlen Einheiten zugeordnet sein sollten.  Nein!
> Auch wenn dann der Compiler  da ein paar Fallstricke erkennen kann ...
> Eine Zahl ist eine Zahl, wenn ich sie z.b. im Menü eingebe oder mit
> min/max teste...

kannst Du noch ein wenig ausführen, worum es hier geht? Geht es noch um 
Rust, oder was ist das Thema?

Klingt eher nach c/Assembler vs. die Moderne?

vlg
 Timm

: Bearbeitet durch User
von Privatfrickler (Gast)


Lesenswert?

Der wo ich bin schrieb:
> google mal "Rust severely disappoints
> me" von Eric Raymond. Am besten auch googeln wer das ist.
>
> Und kuck dir mal die Sprache Zig an und warum sie ins Leben gerufen
> wurde.
> Zitat:
> "Small, simple language. Focus on debugging your application rather than
> debugging your knowledge of your programming language."

Also ist Zig das neue Rust?

https://ziglang.org/
1
const builtin = @import("builtin");
2
const std = @import("std");
3
const io = std.io;
4
const fmt = std.fmt;
5
const os = std.os;
6
7
pub fn main() !void {
8
    var stdout_file = try io.getStdOut();
9
    var stdout_file_stream = io.FileOutStream.init(&stdout_file);
10
    const stdout = &stdout_file_stream.stream;
11
12
    try stdout.print("Welcome to the Guess Number Game in Zig.\n");
13
14
    var seed_bytes: [@sizeOf(u64)]u8 = undefined;
15
    os.getRandomBytes(seed_bytes[0..]) catch |err| {
16
        std.debug.warn("unable to seed random number generator: {}", err);
17
        return err;
18
    };
19
    const seed = std.mem.readInt(seed_bytes, u64, builtin.Endian.Big);
20
    var prng = std.rand.DefaultPrng.init(seed);
21
22
    const answer = prng.random.range(u8, 0, 100) + 1;
23
24
    while (true) {
25
        try stdout.print("\nGuess a number between 1 and 100: ");
26
        var line_buf: [20]u8 = undefined;
27
28
        const line_len = io.readLine(line_buf[0..]) catch |err| switch (err) {
29
            error.InputTooLong => {
30
                try stdout.print("Input too long.\n");
31
                continue;
32
            },
33
            error.EndOfFile, error.StdInUnavailable => return err,
34
        };
35
36
        const guess = fmt.parseUnsigned(u8, line_buf[0..line_len], 10) catch {
37
            try stdout.print("Invalid number.\n");
38
            continue;
39
        };
40
        if (guess > answer) {
41
            try stdout.print("Guess lower.\n");
42
        } else if (guess < answer) {
43
            try stdout.print("Guess higher.\n");
44
        } else {
45
            try stdout.print("You win!\n");
46
            return;
47
        }
48
    }
49
}

von Jan W. R. (Gast)


Lesenswert?

Der wo ich bin schrieb:

>> "Rust severely disappoints me" von Eric Raymond. Am besten auch googeln wer das 
ist.

https://de.wikipedia.org/wiki/Eric_S._Raymond

„…Er bekennt sich zu den Idealen des Libertarismus und ist starker 
Verfechter des Rechts auf Waffenbesitz“
Verfechter des Rechts auf Waffenbesitz leben meiner Meinung nach in 
Irrtum. Ein Grund für mich sich mit Ihm nicht zu beschäftigen, um 
solchen Leuten kein Zuspruch und Anerkennung zu geben


>>"Small, simple language. Focus on debugging your application rather than
>> debugging your knowledge of your programming language."

Ist eine Coole Aussage, leider sehr Pauschal könnte auch auf der 
folgenden Internetseite stehen :
http://www.toodarkpark.org/computers/humor/shoot-self-in-foot.html

Dort sind Witze zu finden wie z.B.  :
>>C++ ◦You accidentally create a dozen instances of yourself and shoot them all in 
the foot. Providing emergency medical assistance is impossible since you can't 
tell which are bitwise copies and which are just pointing at others and saying, 
>>"That's me, over there."

Zitat:
>>"inefficient abstracted programming models where two years down the road
>>   you notice that some abstraction wasn't very efficient, but now all
>>   your code depends on all the nice object models around it, and you
>>   cannot fix it without rewriting your app."

Ist auch eine pauschale Aussage, Populismus.

Ein Amerikanischer Senator leugnete den Klimawandel und warf einen 
Schneeball auf den Boden unter dem Stichwort, „Ist doch kalt draußen“
Es war eine coole Aktion, leide Falsch die Aussage. Jeder von uns weis 
das wir den Klimawandel und Erderwärmung haben.
Mit diesem banalen Beispiel wollte ich sagen das solche Zitate keine 
Argumente sind.


Der Profi selbst weiß wie viel Abstraktion und wie viel Typisierung  wo 
und wie eingesetzt wird.

Gruss,
Jan

von Alex G. (dragongamer)


Lesenswert?

Sehr schön gesagt.

Das klingt wohl jetzt auch pauschal aber denke auch der Entwickler muss 
eben einschätzen ob das Risiko nach einem Jahr fest zu stellen dass man 
falsch abstrahiert hat, grösser ist, als das Risiko nach eine Jahr nicht 
mehr in seinem eigenen Code durch zu blicken weil man grade nicht 
abstrahiert hat.


Am Ende wird man wohl nie alle glücklich machen können mit einer Sprache 
denn grade bei der Frage wie restriktiv die Sprache sein soll, scheiden 
sich die Geister.

von W.S. (Gast)


Lesenswert?

Der wo ich bin schrieb:
> Ich hab mal eine grundsätzliche Frage...
> ...
> Ich bevorzuge C ...

Nö. präziser: GENERAL-NÖ.
Ich bevorzuge C überhaupt nicht, sondern benutze es nur notgedrungen und 
nur dort, wo es keine besseren Alternativen gibt.
Und all diese Pippifax-C-Ersatz-Sprachen sind durchweg eben keine 
Alternativen, geschweige denn bessere Alternativen.

Die Gründe für all dieses Sich-Winden in neuerfundenen Sprachen habe ich 
ja schon viel weiter oben dargelegt: Die Spracherfinder stecken mental 
viel zu tief in der C-Furche und kommen dort zeitlebens nie wieder 
heraus.

Genau DAS ist die Tragik bei all den fruchtlosen Bemühungen.

Wenn man mal bedenkt, wieviel Entwicklungsaufwand vergeigt wird in dem 
Bemühen, eine Art neues C mit allen bisherigen Gewohnheiten aber 
zugleich ohne all die bisherigen Geburtsfehler und Fallstricke und 
natürlich ohne das Aufgeben von bisheriger Syntax, dann wird unsereiner 
melancholisch.

Viel Lärm um nichts, wasch mich ohne mich naßzumachen, nur einmal um 
sich selbst gedreht ohne ein neues (oder wenigstens besseres) Ufer 
erreicht zu haben.

W.S.

von Bernd K. (prof7bit)


Lesenswert?

W.S. schrieb:
> Viel Lärm um nichts, wasch mich ohne mich naßzumachen, nur einmal um
> sich selbst gedreht ohne ein neues (oder wenigstens besseres) Ufer
> erreicht zu haben.

Was schlägst Du also vor? Du scheinst eine Vision zu haben, wie sieht 
sie konkret aus Deine radikale Abkehr von allem dagewesenen die alles 
endlich wirklich besser macht?

von Karl K. (karl2go)


Lesenswert?

Achim S. schrieb:
> Da ins gleiche Horn die 40 Jahre alte Weisheit: die von Mathematikern
> erfunden Zahlen sind kompakt und wunderschön. Sie sollten nicht von
> Ingenieuren zugemüllt werden.

Leider hast Du da eine Kleinigkeit übersehen: Der Zahlenraum in dem 
Mathematiker arbeiten können ist unbegrenzt und unendlich. Der eines 
Computers nicht.

Ergo muss man sich bei der Programmierung auf sinnvolle Einheiten und 
mitunter auch Einheitenvorsätze festlegen, um den vorhandenen Zahlenraum 
sinnvoll nutzen zu können.

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Hallo,

also dieser sehr bekannte Benchmark für Rust

https://benchmarksgame-team.pages.debian.net/benchmarksgame/performance/revcomp.html

mogelt, finde ich, ein bisschen. Das Rust Programm benutzt die externe 
Bibliothek Rayon für parallele Verarbeitung. Rayon gehört nicht zum 
Sprachumfang. Dann müsste ein C/C++ Programm auch externe 
Hilfsbibliotheken benutzen dürfen.

vlg

 Timm

von mh (Gast)


Lesenswert?

Timm R. schrieb:
> Hallo,
>
> also dieser sehr bekannte Benchmark für Rust
>
> https://benchmarksgame-team.pages.debian.net/bench...
Wieso bekannt? Und wieso Benchmark? Es nennt sich selbst benchmarkgame.


Timm R. schrieb:
> mogelt, finde ich, ein bisschen. Das Rust Programm benutzt die externe
> Bibliothek Rayon für parallele Verarbeitung. Rayon gehört nicht zum
> Sprachumfang. Dann müsste ein C/C++ Programm auch externe
> Hilfsbibliotheken benutzen dürfen.
>
> vlg
>
>  Timm
Es wird noch mehr "gemogelt". Beim rust-Program auf Platz 1 steht als 
Author unter anderem "Rust Project Developers". Wo ist das Beispiel mit 
den Authoren "g++ Developers" oder "clang++ Developers"?

Wenn dann in den c++ Beispielen sowas wie:
1
template< class type >
2
struct vector2 : public std::vector<type> {
3
   type &last() { return this->operator[]( std::vector<type>::size() -1 ); }
4
};
oder
1
struct Chunker {
2
protected:
3
   static volatile int printQueue;
4
};
vorkommt, muss man sich schon fragen, was da überhaupt vergleichbar sein 
soll.

von Privatfrickler (Gast)


Lesenswert?

W.S. schrieb:
> Ich bevorzuge C überhaupt nicht, sondern benutze es nur notgedrungen und
> nur dort, wo es keine besseren Alternativen gibt.
> Und all diese Pippifax-C-Ersatz-Sprachen sind durchweg eben keine
> Alternativen, geschweige denn bessere Alternativen.
>
> Die Gründe für all dieses Sich-Winden in neuerfundenen Sprachen habe ich
> ja schon viel weiter oben dargelegt: Die Spracherfinder stecken mental
> viel zu tief in der C-Furche und kommen dort zeitlebens nie wieder
> heraus.
>
> W.S.

Was würdest DU als Alternative vorschlagen?

von mh (Gast)


Lesenswert?

mh schrieb:
> Es wird noch mehr "gemogelt".

Ich muss mich korrigieren. Es wird gemogelt! Die Regeln schreiben das 
zeilenweise Einlesen von stdin vor, wobei die Zeilen max. 60 Zeichen 
lang sind. Das rust-Programm liest deutlich größere Blöcke.

von W.S. (Gast)


Lesenswert?

Bernd K. schrieb:
> Was schlägst Du also vor? Du scheinst eine Vision zu haben, wie sieht
> sie konkret aus Deine radikale Abkehr von allem dagewesenen die alles
> endlich wirklich besser macht?

Hä?
Du tust ja grad so, als ob ICH sowas wie Rust und Konsorten verzapft 
hätte. Nein, hab ich nicht. Ich habe mich durchaus nicht von allem 
Dagewesenen abgekehrt - insbesondere ICH NICHT.

Aber anstatt sich immer neue Sprachen auszudenken, die aussehen und 
funktionieren wie ein verwurschteltes C, hätte ich den Neusprachlern 
eher angeraten, ihren Elan darauf zu verwenden, ihre Herkunfts-Sprache 
zu renovieren, und das gründlich.
Also:
- Headerdateien abschaffen und stattdessen ein echtes Modulsystem auf 
Compilerebene einführen, wo sauber geregelt ist, welche Entitäten des 
Moduls von außen sichtbar und zugänglich sein dürfen und welche nicht.
- verläßliche Datentypen auf Compilerebene einführen. Datentypen haben 
gefälligst problemorientiert zu sein und nicht hardwareorientiert. 
Letzteres hinzukriegen, ist Aufgabe des Compilers und nicht der Sprache.
- boolean einführen
- Strings einführen. Also sowas, wo man ohne Abzählen bis null die Länge 
kennt und die man addieren kann, ohne dabei die berüchtigten 
Pufferüberläufe zu riskieren.
- char von allen Integertypen trennen
- keinerlei Defaults zulassen
- keinerlei Wert von Anweisungen zulassen
- die Deklaration von Konstanten, Typen und Variablen radikal umstellen.
  Bei Variablen
 attribut attribut.. name;
 attribut attribut.. name[indexbereich];
auf
 name : typbezeichnung;
wobei die Typbezeichnung ZUVOR dem Compiler bekannt sein muß.
- die Deklarationen sauber von Anweisungen und Funktionen trennen.
- einen sauberen Zuweisungsoperator einführen, um die Verwendung des "=" 
zum Zuweisen abzuschaffen. Das Gleichheitszeichen ist nämlich ein 
mathematisches Zeichen, das man verdammt noch mal nicht mißbrauchen 
sollte. Ein Ähnliches gilt für den Asterisk (das Sternchen) und das Et 
(Kaufmannsund, "&"), was man vom At ("@") unterscheiden sollte. 
Heutzutage ist das At den Leuten ohnehin weitaus geläufiger als das Et 
und das Sternchen für die bisherigen Pointeroperationen.
- Gleichheit für alle Pointeroperationen einführen. Dabei fliegen 
Sternchen und Et raus, ebenso "->", und das Ganze wird mit dem Punkt für 
Members ersetzt.
- Einführen von Variablenreferenzen anstelle von Pointern als Argumente 
zwecks besserer Kontrolle durch den Compiler.

So, reicht das für den Anfang? Bin mal gespannt, ob jetzt ein Gekreisch 
hier einsetzt.

Man muß ja nicht alles auf einmal einführen, damit das Gezeter der ewig 
Gestrigen sich auf einen größeren Zeitraum verteilt.

W.S.

von Bernd K. (prof7bit)


Lesenswert?

W.S. schrieb:
> Aber anstatt sich immer neue Sprachen auszudenken, die aussehen und
> funktionieren wie ein verwurschteltes C, hätte ich den Neusprachlern
> eher angeraten, ihren Elan darauf zu verwenden, ihre Herkunfts-Sprache
> zu renovieren, und das gründlich.
> Also:

Ok, also schaun wir mal Punkt für Punkt:

> - Headerdateien abschaffen und stattdessen ein echtes Modulsystem auf
> Compilerebene einführen, wo sauber geregelt ist, welche Entitäten des
> Moduls von außen sichtbar und zugänglich sein dürfen und welche nicht.

check

> - verläßliche Datentypen auf Compilerebene einführen. Datentypen haben
> gefälligst problemorientiert zu sein und nicht hardwareorientiert.

check

> Letzteres hinzukriegen, ist Aufgabe des Compilers und nicht der Sprache.

? Ein Typsystem mit solchen Garantien muß immer Teil der 
Sprachdefinition sein

> - boolean einführen

check

> - Strings einführen. Also sowas, wo man ohne Abzählen bis null die Länge
> kennt und die man addieren kann, ohne dabei die berüchtigten
> Pufferüberläufe zu riskieren.

check

> - char von allen Integertypen trennen

check

> - keinerlei Defaults zulassen

?

> - keinerlei Wert von Anweisungen zulassen

check

> - die Deklaration von Konstanten, Typen und Variablen radikal umstellen.
>   Bei Variablen
>  attribut attribut.. name;
>  attribut attribut.. name[indexbereich];
> auf
>  name : typbezeichnung;
> wobei die Typbezeichnung ZUVOR dem Compiler bekannt sein muß.

check

> - die Deklarationen sauber von Anweisungen und Funktionen trennen.

? Die Syntax ist klar, es ist deutlich ersichtlich was eine 
Variablenddeklaration ist und was nicht, es gibt sogar ein eigenes 
Keyword dafür "let", ist das getrennt genug?
also check (für meine Ansprüche zumindest)

> - einen sauberen Zuweisungsoperator einführen, um die Verwendung des "="
> zum Zuweisen abzuschaffen. Das Gleichheitszeichen ist nämlich ein
> mathematisches Zeichen, das man verdammt noch mal nicht mißbrauchen
> sollte. Ein Ähnliches gilt für den Asterisk (das Sternchen) und das Et
> (Kaufmannsund, "&"), was man vom At ("@") unterscheiden sollte.
> Heutzutage ist das At den Leuten ohnehin weitaus geläufiger als das Et
> und das Sternchen für die bisherigen Pointeroperationen.

Reine Kosmetik. Ob er = oder := oder <- oder sonstwie geschrieben wird 
ist schnurz. Rust hat einen "sauberen" Zuweisungsoperator, der ganze 
andere Kram mit & vs @ ist auch reine Kosmetik, Pascal hätte auch mit & 
statt @ funktioniert und keiner hätte sich daran gestört. Der einzige 
valide Kritikpunkt wäre daß man argumentieren könnte daß das Sternchen 
zum Dereferenzieren auf der falschen Seite steht (ist mir auch sofort 
ins Auge gestochen, bei Pascal zum Beispiel steht das Dach auf der 
richtigen Seite) aber selbst das ist nur minimale Kosmetik die hinter 
weit wichtigerem zurücktritt.

also check

> - Gleichheit für alle Pointeroperationen einführen. Dabei fliegen
> Sternchen und Et raus, ebenso "->", und das Ganze wird mit dem Punkt für
> Members ersetzt.

? Die Sprache soll verständlich sein, also sollte man schon sehen was 
man schreibt, denselben Operator für völlig unterschiedliche 
Operationen?
Unfug

Und übrigens das -> hat in Rust überhaupt nichts mit Pointeroperationen 
zu tun, ich weiß nicht warum Du das jetzt anführst, das -> symbolisiert 
den Abbildungspfeil wie man ihn aus der Mathematik kennt bei der 
Deklaration einer Funktion, es zeigt auf den Zieltyp der Abbildung, zum 
Beispiel so:

fn foo(x: i32) -> i32

> - Einführen von Variablenreferenzen anstelle von Pointern als Argumente
> zwecks besserer Kontrolle durch den Compiler.

Check


Also was war nochmal Deine Kritik an Rust? Als Pascal-Liebhaber müßtest 
Du es eigentlich lieben, endlich ein "Pascal" ohne Boilerplate, dann 
sogar noch mit Typinferenz und die Kompilezeit-Typsicherheit gleich 
nochmal ins übernächste Level katapultiert! Was will man mehr?

: Bearbeitet durch User
von Yalu X. (yalu) (Moderator)


Lesenswert?

Da musste ich schon ein wenig grinsen :)

Erst schreibt W.S.:

W.S. schrieb:
> Rust ist ganz offensichtlich nur ein weiterer Vorbrenner für C. Sieht ja
> auch fast genauso aus, ist nur noch ein wenig unübersichtlicher.

Auf die Nachfrage hin, wie denn seine Vision aussehe, schreibt er:

W.S. schrieb:
> Aber anstatt sich immer neue Sprachen auszudenken, die aussehen und
> funktionieren wie ein verwurschteltes C, hätte ich den Neusprachlern
> eher angeraten, ihren Elan darauf zu verwenden, ihre Herkunfts-Sprache
> zu renovieren, und das gründlich.
> Also:
> ...

Da, wo die ... stehen, beschreibt er Features, die zu 95% von Rust
umgesetzt wurden und die Bernd netterweise Stück für Stück aufgedröselt
hat:

Bernd K. schrieb:
> check
> check
> check
> ...

@W.S:

Bist du sicher, dass deine Vision der optimalen Programmierpsrache ein
Vorbrenner für C ist, der fast genauso aussieht und nur ein wenig
unübersichtlicher ist? ;-) SCNR

Wobei man sagen muss, dass die meisten der von dir aufgeführten
Forderungen von fast jeder neueren Programmiersprache erfüllt werden.
Das, was die Sprachen wirklich voneinander unterscheidet, beschränkt
sich nicht auf solche Oberflächlichkeiten.

: Bearbeitet durch Moderator
von Privatfrickler (Gast)


Lesenswert?

Bernd K. schrieb:
> Reine Kosmetik. Ob er = oder := oder <- oder sonstwie geschrieben wird
> ist schnurz.

Gerade die "Kosmetik" zwingt aber leidlich zum permanenten Umdenken und 
schafft somit unnötig zusätzliche Komplexität. Wenn fünf 
Programmiersprachen fünf verschiedene Symbole für Zuweisungen verwenden, 
dann hast du fünf-fachen Aufwand diese zu unterscheiden. Und es bleibt 
ja nicht bei diesem einen Umstand. Für den Vergleich gibt es dann 
vielleicht wieder fünf verschiedene Symbole. Für einen Zeiger nochmals 
fünf weitere Unterschiedlichkeiten. Vor lauter Symboljongliererei 
verbraucht man dann mehr Hirnschmalz das noch auseinanderzuhalten als 
sich dem eigentlichen Sinn der Programmiererei zuzuwenden.

von Privatfrickler (Gast)


Lesenswert?

Oder nehmt mal die ausufernde
1
const

Verwendung aus dem Beispielcode von ziglang aus meinem Post weiter oben.

Warum muss eine sich verändernde Zeilenlänge unbedingt ein const davor 
tragen? Das erscheint doch irgendwie widersinnig!
1
const line_len = io.readLine(line_buf[0..]) catch |err| switch (err)

Mit Intuition kommt man jedenfalls nicht darauf.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Privatfrickler schrieb:
> Warum muss eine sich verändernde Zeilenlänge unbedingt ein const davor
> tragen? Das erscheint doch irgendwie widersinnig!
> const line_len = io.readLine(line_buf[0..]) catch |err| switch (err)

Wo ändert sich line_len? Ich sehe da nur lesende Zugriffe.

Privatfrickler schrieb:
> Oder nehmt mal die ausuferndeA
>
> const
>
> Verwendung

Deswegen sind in Rust alle Variablen defaultmäßig const, so dass dort
nichts ausufert. Nur dijenigen Variablen, die überschrieben werden
sollen, werden speziell deklariert, nämlich mit "mut".

von Privatfrickler (Gast)


Lesenswert?

Yalu X. schrieb:
> Wo ändert sich line_len? Ich sehe da nur lesende Zugriffe.

Also ich sehe zumindest keine Zeichenkette die Konstant bleibt, sonst 
gäbe es ja kein
1
try stdout.print("Input too long.\n");

Aber vielleicht habe da auch einfach eine andere Sichtweise als du?

von Bernd K. (prof7bit)


Lesenswert?

Privatfrickler schrieb:
> Gerade die "Kosmetik" zwingt aber leidlich zum permanenten Umdenken und
> schafft somit unnötig zusätzliche Komplexität. Wenn fünf
> Programmiersprachen fünf verschiedene Symbole für Zuweisungen verwenden,

Die überwiegende Mehrheit inclusive der Zielgruppe C(++)-Umsteiger 
verwendet ja schon das simple = für die Zuweisung, also hat Rust die 
richtige Wahl getroffen. Ein := hätt ich aber genauso akzeptiert, ich 
mach noch viel Pascal nebenher, Probleme mit dem Umdenken kann ich nicht 
feststellen. Ab und zu vielleicht mal ein Vertipper wenn man zehnmal am 
Tag hin- und herwechselt aber der Compiler meckert sofort, keine große 
Sache.

Ich find das überhaupt nicht dramatisch.

Bei vielen (allen) Sachen muß man "umdenken", nicht nur bei der Syntax, 
wenn man die Sprache wechselt, mir rutscht auch zweimal die Woche ein ; 
am Zeilenende in Python raus und sofort klopft mir der Linter auf die 
Finger, ich empfinde das aber nicht als Erschwernis, mit der Zeit 
beherrscht man das im Schlaf und kann in 2 Sekunden fast vollständig 
umswitchen ohne nachzudenken.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Privatfrickler schrieb:
> Yalu X. schrieb:
>> Wo ändert sich line_len? Ich sehe da nur lesende Zugriffe.
>
> Also ich sehe zumindest keine Zeichenkette die Konstant bleibt, sonst
> gäbe es ja kein
> try stdout.print("Input too long.\n");
>
> Aber vielleicht habe da auch einfach eine andere Sichtweise als du?

Const bedeutet in diesem Zusammenhang, dass die Variable, nachdem sie
einmal initialisiert, d.h. an einen Wert gebunden worden ist, während
ihrer gesamten Lebensdauer diesen Wert beibehält. Das bedeutet nicht
unbedingt, dass der Wert schon zur Compilezeit feststeht.

Auch die Zeichenkettenvariable line_buf könnte als const deklariert
werden, wenn es eine Möglichkeit gäbe, sie direkt bei ihrer Deklaration
zu initialisieren, etwa mit

   const line_buf: [20]u8 = io.readLine();

Da die Funktion io.readLine() die gelesene Zeichenkette aber nicht als
Funktionswert, sondern in einem variablen Funktionsargument zurückgibt,
gibt es diese Möglichkeit nicht. Deswegen wird line_buf zunächst mit
"undefined" initialisiert und danach durch io.readLine() überschrieben.

In Rust ist die "Constness" ebenso definiert, nur dass man dort das
Schlüsselwort "const" nicht explizit hinschreibt.

: Bearbeitet durch Moderator
von Karl K. (karl2go)


Lesenswert?

Privatfrickler schrieb:
> Gerade die "Kosmetik" zwingt aber leidlich zum permanenten Umdenken und
> schafft somit unnötig zusätzliche Komplexität. Wenn fünf
> Programmiersprachen fünf verschiedene Symbole für Zuweisungen verwenden,
> dann hast du fünf-fachen Aufwand diese zu unterscheiden.

Ja aber wenn es eine Sprache so richtig verkackt hat wie C mit = und ==, 
dann muss man diesen Fehler wirklich nicht ständig wieder machen (JS, 
Python, Rust...).

Das hat schon was von Einsteins Satz über die Definition von Wahnsinn.

von Karl K. (karl2go)


Lesenswert?

Yalu X. schrieb:
> Const bedeutet in diesem Zusammenhang, dass die Variable, nachdem sie
> einmal initialisiert, d.h. an einen Wert gebunden worden ist, während
> ihrer gesamten Lebensdauer diesen Wert beibehält. Das bedeutet nicht
> unbedingt, dass der Wert schon zur Compilezeit feststeht.

Das ist ne ziemlich ungewöhnliche Definition einer Konstanten, finde 
ich. So wie: Wir wissen zwar noch nicht, wie groß Pi diesmal sein wird, 
aber wenn wir erstmal nen Wert haben lassen wir ihn so.

Gerade für Embedded finde ich das verwirrend, werden Konstanten dort 
doch oft direkt in den Code eingebaut (ldi, cpi, subi), was ja irgendwie 
schwer geht wenn sie noch nicht feststehen.

Also muss der Compiler wieder unterscheiden zwischen "echten" Konstanten 
und - naja, nennen wir sie Variablen.

von Privatfrickler (Gast)


Lesenswert?

Yalu X. schrieb:
> Deswegen wird line_buf zunächst mit
> "undefined" initialisiert und danach durch io.readLine() überschrieben.

Dagegen habe ich ja auch überhaupt nichts einzuwenden. Man möchte einen 
Zeichenpuffer bereitstellen, dessen Größe man zunächst nicht angeben 
möchte (wobei das ja an sich schon irrig ist, denn dann müsste man ja 
MÖGLICHERWEISE AUCH von ausgehen, dass der Zeichenpuffer beispielsweise 
auch unsinnig groß (1 TB) werden könnte, aber wer will das schon?). Also 
bekommt er ein "undefined" aufgepappt und geht damit in die while(true) 
Endlosschleife. Nun kommt der Lesevorgang (io.readline). Der wird doch 
immer wieder ausgeführt, solange der catch nix schlimmes signalisiert. 
Also wird der Zeilenpuffer auch immer wieder mit anderen Wertlängen 
beschrieben. Was ist daran nun Konstant?

Mich stört einfach der Begriff const hier. Wenn es nur darum geht, 
auszuschließen, dass sonstwie (an anderer Codestelle) auf den Puffer 
zugegriffen wird, wäre doch so was wie ein blocked viel angebrachter.

anstatt
1
const line_len = io.readLine(line_buf[0..]) catch |err| switch (err)
müsste es beispielsweise heißen
1
blocked line_len = io.readLine(line_buf[0..]) catch |err| switch (err)

const. wäre dann nur noch für wirklich konstante Längen verwendbar

Wie auch immer. Sowas nervt mich eben, hält einfach von anderem ab und 
stielt unnütz meine Zeit.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Karl K. schrieb:
> Ja aber wenn es eine Sprache so richtig verkackt hat wie C mit = und ==,
> dann muss man diesen Fehler wirklich nicht ständig wieder machen (JS,
> Python, Rust...).

Das Problem bei C ist ja nicht, dass die Operatoren = und == heißen,
sondern dass eine Zuweisung (bspw. a=13) ein Ausdruck mit einem
Ergebniswert (im Beispiel: 13) ist, der als Bedingung in einem if- oder
while- oder for-Konstrukt verwendet werden kann, bspw. in if(a=13) ...,
was oft nicht beabsichtigt ist.

In Python führt if a=13: ... zu einem Syntaxfehler. Aber auch die
C-Compiler sind mittlerweile so weit, dass sie bei if(a=13) ..., obwohl
syntaktisch korrekt, wenigstens eine Warnung auisgeben.

Karl K. schrieb:
> Yalu X. schrieb:
>> Const bedeutet in diesem Zusammenhang, dass die Variable, nachdem sie
>> einmal initialisiert, d.h. an einen Wert gebunden worden ist, während
>> ihrer gesamten Lebensdauer diesen Wert beibehält. Das bedeutet nicht
>> unbedingt, dass der Wert schon zur Compilezeit feststeht.
>
> Das ist ne ziemlich ungewöhnliche Definition einer Konstanten, finde
> ich. So wie: Wir wissen zwar noch nicht, wie groß Pi diesmal sein wird,
> aber wenn wir erstmal nen Wert haben lassen wir ihn so.

Im englischen Sprachgebrauch unterscheidet man zwischen

  compile-time constant

und

  immutable

In C++ werden dafür die beiden Schlüsselwörter "constexpr" und "const"
verwendet, um diesen Unterschied deutlich zu machen.

In der Mathematik wäre eine Konstante wie π oder e compile-time constant
und eine gewöhnliche Variable immutable. Mutable Variablen gibt es in
der mathematischen Formelsprache nicht, da es dort auch keine
Zuweisungen gibt.

: Bearbeitet durch Moderator
von Privatfrickler (Gast)


Lesenswert?

Yalu X. schrieb:
> Mutable Variablen gibt es in
> der mathematischen Formelsprache nicht, da es dort auch keine
> Zuweisungen gibt.

Was genau meinst du denn jetzt mit "mathematischer Formelsprache"?

y = 1 Konstant
y = x für x e R nicht mehr allzu Konstant oder?

von Yalu X. (yalu) (Moderator)


Lesenswert?

Privatfrickler schrieb:
> Nun kommt der Lesevorgang (io.readline). Der wird doch
> immer wieder ausgeführt, solange der catch nix schlimmes signalisiert.
> Also wird der Zeilenpuffer auch immer wieder mit anderen Wertlängen
> beschrieben. Was ist daran nun Konstant?

Der Zeilenpuffer kann ja aus dem o.g. Grund sowieso nicht als const
deklariert werden. Aber nehmen wir wieder line_len als Beispiel:

Diese (immutable) Variable ist innerhalb der While-Rumpfs deklariert.
Ihre Lebensdauer erstreckt sich damit von der Zeile, in der sie
deklariert wird bis zum Ende des While-Rumpfs, also bis zur schließenden
geschweiften Klammer in der zweitletzten Codezeile.

Mit jedem Schleifendurchlauf wird die Variable (zumindest formal) neu
geschaffen und am Ende dieses Schleifendurchlaufs wieder zerstört.
Dazwischen wird die Variable kein einziges Mal überschrieben.

> Mich stört einfach der Begriff const hier. Wenn es nur darum geht,
> auszuschließen, dass sonstwie (an anderer Codestelle) auf den Puffer
> zugegriffen wird, wäre doch so was wie ein blocked viel angebrachter.

Ich gebe dir recht, dass das Schlüsselwort "const" etwas unglücklich
gewählt ist. Aber auch der Begriff "blocked" würde mich in diesem
Zusammenhang stören. Mit "blocked" verbinde ich etwas Laufendes, was
plötzlich angehalten wird. Vielleicht können wir uns ja auf "immutable"
als besten Kompromiss einigen.

Oder man geht der Diskussion ganz aus dem Weg, indem man wie in Rust
solche const/immutable Variablen gar nicht explizit als solche
deklariert :)

: Bearbeitet durch Moderator
von Yalu X. (yalu) (Moderator)


Lesenswert?

Privatfrickler schrieb:
> Yalu X. schrieb:
>> Mutable Variablen gibt es in
>> der mathematischen Formelsprache nicht, da es dort auch keine
>> Zuweisungen gibt.
>
> Was genau meinst du denn jetzt mit "mathematischer Formelsprache"?
>
> y = 1 Konstant
> y = x für x e R nicht mehr allzu Konstant oder?

Richtig, deswegen heißt man y ja auch eine Variable und keine Konstante.
y ist aber auch nicht so variabel wie eine mutable Variable in einer
Programmiersprache. In C kann man schreiben:

1
  y = 3;
2
  y = y + 1;

wodurch y am Ende den Wert 4 hat.

In der Mathematik wäre die zweite Zeile entweder eine nicht lösbare
Gleichung oder eine wenig sinnhafte rekursive Definition für y.

Als rekursive Definition wird die zweite Zeile übrigens auch in
Funktionalsprachen (die stark von der mathematischen Schreib- und
Denkweise inspiriert sind) interpretiert. Auch dort ergibt sie praktisch
keinen Sinn.

Der Ausdruck x ∈ ℝ bedeutet in der Mathematik nicht, dass x alle paar
Sekunden einen neuen Wert annimmt. Er bedeutet vielmehr, dass x einen
beliebigen Wert annehmen darf, der aber im nachfolgenden Text (wenn
bspw. irgendwelche Sätze aufgestellt werden, in denen y vorkommt) fest
bleibt.

von Privatfrickler (Gast)


Lesenswert?

Yalu X. schrieb:
> Der Zeilenpuffer kann ja aus dem o.g. Grund sowieso nicht als const
> deklariert werden.

Es ging ja auch nicht um den Inhalt des Zeilenpuffers

also ob da "abcde" oder "12345" drin steht, sondern um die Länge also
"abc" (3 Zeichen + Zeilenende) oder "dieKatzeLiegtImSchnee" (21 Zeichen 
+ Zeilenende)

> Aber nehmen wir wieder line_len als Beispiel:
> Diese (immutable) Variable ist innerhalb der While-Rumpfs deklariert.

Richtig.

> Ihre Lebensdauer erstreckt sich damit von der Zeile, in der sie
> deklariert wird bis zum Ende des While-Rumpfs, also bis zur schließenden
> geschweiften Klammer in der zweitletzten Codezeile.

Korrekt.

> Mit jedem Schleifendurchlauf wird die Variable (zumindest formal) neu
> geschaffen und am Ende dieses Schleifendurchlaufs wieder zerstört.

Einverstanden. Das habe ich in der Tat übersehen.

> Dazwischen wird die Variable kein einziges Mal überschrieben.

Es droht aber auch kein einziges Überschreiben. Von nirgendwo.
line_len dient der immutable Variablen guess, um die Methode 
parseUnsigned() mit der richtigen Pufferlänge beim Parsen zu versorgen.

Mir kommt das vor als ob hier eine "Gefahr" bekämpft werden soll, die 
gar nicht besteht. Wenn line_len mutable wäre, was würde sich hier 
ändern?

>> Mich stört einfach der Begriff const hier. Wenn es nur darum geht,
>> auszuschließen, dass sonstwie (an anderer Codestelle) auf den Puffer
>> zugegriffen wird, wäre doch so was wie ein blocked viel angebrachter.
>
> Der Begriff "blocked" würde mich in diesem Zusammenhang stören. Mit
> "blocked" verbinde ich etwas, das blockiert, also angehalten wird.
> Vielleicht können wir uns ja auf "immutable" als besten Kompromiss
> einigen.

Ich meinte halt irgend ein prägnantes Schlüsselwort, das dem 
Programmierer verdeutlicht, diesen Wert von außen nicht ändern zu 
dürfen. In dieser Konstellation geht das aber eh nicht.

Stellen wir uns aber einen Moment vor, line_len wäre außerhalb der 
while-Schleife deklariert. Die Variable line_len würde also nicht mit 
jedem Schleifendurchlauf neu angelegt und wäre somit auch nicht mehr 
ECHT const, erhielte sie doch von readline bei jedem Schleifendurchlauf 
einen neuen Wert zugewiesen.

Würde der Compiler für const. line_len nun eine Fehlermeldung werfen?
Falls ja, dann wäre ja alles wie (intuitiv) erwartet.
Falls nein, wäre der Begriff const hier eigentlich unsinnig.

Wäre die Variable außerhalb der while-Schleife als immutable line_len 
deklariert, würde das vielleicht bedeuten, der Programmierer darf 
line_len nicht (ohne weiteres) im Wert verändern (ergibt 
Compilerfehler?), eine Methode wie io.readline zur Laufzeit aber darf 
das und der Compiler meckert nicht?

> Oder man geht der Diskussion ganz aus dem Weg, indem man wie in Rust
> solche const/immutable Variablen gar nicht explizit als solche
> deklariert :)

Wir nähern uns.

:)

von Privatfrickler (Gast)


Lesenswert?

Yalu X. schrieb:
> Der Ausdruck x ∈ ℝ bedeutet in der Mathematik nicht, dass x alle paar
> Sekunden einen neuen Wert annimmt. Er bedeutet vielmehr, dass x einen
> beliebigen Wert annehmen darf, der aber im nachfolgenden Text (wenn
> bspw. irgendwelche Sätze aufgestellt werden, in denen y vorkommt) fest
> bleibt.

Ja, aber es bedeutet auch nicht, dass x zwingend nur EINEN bestimmten 
Wert annehmen muss. Wie willst du eine einfache gerade in der Ebene auf 
EINEN bestimmten Wert vereinfachen? Das sind nun mal unendlich viele 
Werte, die so eine einfache Gerade definieren. Um damit zu rechnen 
vereinfachen wir halt die Gerade auf 2 konkrete Punktpaare (x0,y0), 
(x1,y1).

von malsehen (Gast)


Lesenswert?

Konstanten sind variabel, bis sie
verändert werden.

Niclaus Wirth

Habe ich mal gehört, himself

von Hans (Gast)


Lesenswert?

Privatfrickler schrieb:
> Yalu X. schrieb:
>> Der Ausdruck x ∈ ℝ bedeutet in der Mathematik nicht, dass x alle paar
>> Sekunden einen neuen Wert annimmt. Er bedeutet vielmehr, dass x einen
>> beliebigen Wert annehmen darf, der aber im nachfolgenden Text (wenn
>> bspw. irgendwelche Sätze aufgestellt werden, in denen y vorkommt) fest
>> bleibt.
>
> Ja, aber es bedeutet auch nicht, dass x zwingend nur EINEN bestimmten
> Wert annehmen muss. Wie willst du eine einfache gerade in der Ebene auf
> EINEN bestimmten Wert vereinfachen? Das sind nun mal unendlich viele
> Werte, die so eine einfache Gerade definieren. Um damit zu rechnen
> vereinfachen wir halt die Gerade auf 2 konkrete Punktpaare (x0,y0),
> (x1,y1).

naja, das wäre x ∈ ℝ² in einem x ∈ ℝ³ Raum... das hat nix mit dem 
beispiel zu tun. mehr dimensionale datentypen können die wenigsten 
sprachen. (complex und simd extentions ausgenommen).

aber tu dir nix an, hier in diesem forum gibt es nur python und 
assembler (habe ich in einem anderen thread lernen müssen).


Jedenfalls hätte ich nebenbei was sinnvolles beizutragen:


S. R. schrieb:
> nga schrieb:
>> Ich habe mir mit C und C++ schon öfters effizient in den Fuß geschossen,
>> was gerade auf µCs oft nicht direkt auffällt, das es keinen SegFault wie
>> auf dem PC gibt
>
> Den gibt es schon, heißt nur HardFault und führt normalerweise zu einem
> Reset. Unterbindet man das (z.B. durch einen eigenen HardFault-Handler),
> dann unterscheidet er sich nicht besonders von seinem PC-Pendanten.
> Weglaufende Pointer fängt man damit relativ gut ein.


eigentlich läuft auf einem ARM Cortex sehr vieles auf einen HardFault 
raus (wenn man nicht explizit was dagegen tut) und normalerweise sollte 
das sogar ein
1
while(1);
 ergeben (uuhhhhh schon wieder diese pöse syntax) und keinen reset.

ich würde mir grundsätzlich im startup file vom gdb einen breakpoint auf 
dein hardfault-symbol setzen.
Damit bekommst du dann im normalfall auch alle busfaults usw mit.

Aus den registern wird man mit ein bisschen Übung eigentlich recht 
schnell schlau. Man muss sich nur einmal die paar seiten in der ARM 
Bibel durchlesen um zu verstehen was wo steht.

btw. z.B. der gcc zeigt dir mit -Wall und -Wextra viele "beinschüsse" 
als warning an...

nga schrieb:
> Ich gehe stark davon aus, dass pure C/C++ eine
> kleinere Runtime hat (und damit erst einmal ein kleineres Binary), aber
> bei größeren Projekten sieht das evtl. anders aus (kann ich mangels
> einem solchen Projekt nicht testen).

C/C++ hat keine "runtime" ... die crt0 ist mehr oder weniger eine 
funktion die speicherbereiche initialisiert. das ist mit anderen 
compiler sprachen aber nicht anders.

am PC kommt einiges dazu weil um das betriebsystem "herumgebaut" wird.

Speicher ist im übrigen ein ziemlich dummer benchmark heutzutage... 
kleiner asm code muss nicht notwendigerweise schneller sein wie 
längerer.

dazu kommt, dass sogar die cortex prozessoren pipelines und dma haben. 
damit ist jegliches "ausrechnen" von zyklen eigentlich obsolet.


beim gcc und llvm sollte die sprache außerdem ziemlich wurscht sein...

im endeffekt steht zwischen source und binary immer irgend ein 
intermediate code...

also nimm was du für effizent empfindest.

73

von Privatfrickler (Gast)


Lesenswert?

Der wo ich bin schrieb:
> An Alex G.:
>
> Anstatt durch die Blume zu implizieren ich sei kein Profi, hätte keine
> Ahnung oder bin einfach zu dumm, google mal "Rust severely disappoints
> me" von Eric Raymond. Am besten auch googeln wer das ist.

Da habe ich auch noch einen gefunden

https://hackernoon.com/why-im-dropping-rust-fd1c32986c88?gi=c50c80e066a1

"Conclusion

The problems I've encountered in option 1 through 3 leave me to believe 
that option 4, making bindings to C, would be the only working 
alternative for the library I'm trying to write. And now that I'm at 
this stage, I'm thinking, why write bindings to C when I could just as 
well be writing in C? Or C++?

There are some good things about Rust as a programming language. I quite 
like the way Match works. I like the idea behind traits much like the 
interfaces in Go, I like cargo as a packaging tool. But when it comes to 
the implementation details of traits, reference counting and impossible 
to overwrite behaviour of the compiler, I'm just forced to say: no. This 
will not work for me.

I sincerely hope that people continue to use and improve Rust. But I 
want to write games. Not wrestle with the compiler or having to write 
RFCs to make the language more favourable towards my goals."

Diesen Text inkl. Verweis auf Beispiele schrieb er aber Sep 11, 2016. 
Vielleicht ist der Inhalt damit auch nicht mehr ganz taufrisch. Das 
müssen andere beurteilen.

von Vincent H. (vinci)


Lesenswert?

Privatfrickler schrieb:
> Da habe ich auch noch einen gefunden
>
> https://hackernoon.com/why-im-dropping-rust-fd1c32986c88?gi=c50c80e066a1

Nachdem du offensichtlich nicht einmal verstehst warum const wichtig ist 
oder dich mit der Lappalie der Wortwahl herumschlägst kann ich mir nicht 
vorstellen dass du auch nur eines der angesprochenen Probleme aus dem 
Link verstehst...

Wer das Konzept von Immuteability für unwichtig hält dem lege ich 
folgenden Talk ans Herz:
https://youtu.be/sPhpelUfu8Q

von W.S. (Gast)


Lesenswert?

Yalu X. schrieb:
> Bist du sicher, dass deine Vision der optimalen Programmierpsrache ein
> Vorbrenner für C ist, der fast genauso aussieht und nur ein wenig
> unübersichtlicher ist? ;-) SCNR

gröhl...

Erstens ist es keineswegs meine Vision einer optimalen 
Programmiersprache, denn die war und ist schlichtweg Pascal.

Zweitens ist das, was ich beschrieben habe, eine Renovierung von C - mit 
dem Zweck, daß die Leute, die sich ansonsten Rust2, Tust, FRust und so 
weiter ausgedacht hätten - also alles Neuerfindungen, die dennoch 
genauso aussehen wie C und Basic - ihre Lebensenergie stattdessen in's 
Renovieren von C stecken würden.

Natürlich würde ein renoviertes C noch immer so ähnlich aussehen wie das 
bisherige C. Was denn sonst? Die Leute wie deine Rust-Erfinder können 
doch erwiesenermaßen nichts anderes als C (oder WOLLEN nichts anderes, 
was auf's Gleiche hinausläuft).

Und nochwas:

Warum seid ihr hier so unendlich kindisch?

Aus den Tagen früher Pubertät ist mir erinnerlich, daß wir Schulbuben 
uns damit übertreffen wollten, ob wie ganz besonders ausschließlich 
nur blonde Mädel oder rothaarige Mädel toll fänden.

Genauso geht das hier bei euch mit den Programmiersprachen.

Auch du glaubst, daß mein von mir an den Horizont von C-Programmierern 
angepaßter Vorschlag mein eigenes Ideal sei. Welch ein Irrtum. Oder 
eine böswillige Unterstellung.

W.S.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Privatfrickler schrieb:
> Stellen wir uns aber einen Moment vor, line_len wäre außerhalb der
> while-Schleife deklariert. Die Variable line_len würde also nicht mit
> jedem Schleifendurchlauf neu angelegt und wäre somit auch nicht mehr
> ECHT const, erhielte sie doch von readline bei jedem Schleifendurchlauf
> einen neuen Wert zugewiesen.
>
> Würde der Compiler für const. line_len nun eine Fehlermeldung werfen?

Ja.

> Falls ja, dann wäre ja alles wie (intuitiv) erwartet.

Freut mich :)

von Yalu X. (yalu) (Moderator)


Lesenswert?

W.S. schrieb:
> Zweitens ist das, was ich beschrieben habe, eine Renovierung von C - mit
> dem Zweck, daß die Leute, die sich ansonsten Rust2, Tust, FRust und so
> weiter ausgedacht hätten - also alles Neuerfindungen, die dennoch
> genauso aussehen wie C und Basic - ihre Lebensenergie stattdessen in's
> Renovieren von C stecken würden.

Lass mich mal zusammenfassen:

1. Wie Bernd gezeigt hat, erfüllt Rust weitgehendst deine Anforderungen
   an ein renoviertes C.

2. Nach deiner Aussage sieht Rust sogar aus wie C.

Damit ist doch Rust genau das von dir propagierte, renovierte C,
zumindest müsste es das – nach allem was du geschrieben hast – aus
deiner Sicht sein.

Leute, die sich schon einmal wenigstens eine halbe Stunde mit Rust
beschäftigt haben, sehen das natürlich komplett anders. Und das zu
Recht, denn Rust hat zwar ein paar Kleinigkeiten mit C gemeinsam, wurde
aber im Wesentlichen von anderen Sprachen beeinflusst, die (mit Ausnahme
von C++) nicht das Geringste mit C zu tun haben:

  https://doc.rust-lang.org/reference/influences.html

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


Lesenswert?

Yalu X. schrieb:
> Im englischen Sprachgebrauch unterscheidet man zwischen
>
>   compile-time constant
>
> und
>
>   immutable
>
> In C++ werden dafür die beiden Schlüsselwörter "constexpr" und "const"
> verwendet, um diesen Unterschied deutlich zu machen.

Danke. Endlich mal eine einfache und kurze Erklärung, was der
Unterschied zwischen "constexpr" und "const" ist.

von W.S. (Gast)


Lesenswert?

Bernd K. schrieb:
> ? Die Syntax ist klar, es ist deutlich ersichtlich was eine
> Variablenddeklaration ist und was nicht, es gibt sogar ein eigenes
> Keyword dafür "let", ist das getrennt genug?
> also check (für meine Ansprüche zumindest)

Nein, so nicht.

Wenn man es überhaupt zuläßt, Typ- Konstanten- oder 
Variablendeklarationen innerhalb des Codes zuzulassen, dann öffnet das 
den Freiraum für Pfusch, was wir ja deutlichst in C bisher gesehen 
haben.
Erinnerst du dich an sowas:
static long otto = 77;
Die nächst hirnrissigere Stufe wäre dann sowas:
if((static long otto = 77)==karlheinz)...;
Also: saubere Trennung und basta.


Bernd K. schrieb:
> ? Die Sprache soll verständlich sein, also sollte man schon sehen was
> man schreibt, denselben Operator für völlig unterschiedliche
> Operationen?
> Unfug

Kein Unfug. Es ist nämlich die gleiche Operation, lediglich einmal via 
Referenz sprich Zeiger.

Ich erklär's dir:
Wenn eine Variable vom Typ Pointer ist, dann weiß der Compiler und der 
Codeschreiber, daß das ein Pointer ist. Folglich sollte man das auch 
nicht nochmal durch überflüssige Schreibweisen doppelmoppeln. Bei 
Funktionsargumenten via Referenz tut man das ja auch nicht.

Kleines Beispiel aus dem Stegreif:
( ":=" von Pascal übernommen, wäre aber diskutabel)
typ
 Typ1 : struct { X : int; Y : int };
 Typ2 : pointer of Typ1;

var
 VAVA : Typ1;
 POIN : Typ2;
 POI2 : Typ2;

code
 VAVA.X := 7;    // Zuweisungen an Members
 VAVA.Y := -3;
 POIN   := new(Typ1);
 POIN.X := 14;   // auch Zuweisung an Members
 POIN.Y :=  0;
 POI2   := @VAVA;

Da also jeder weiß, daß POIN ein Zeiger ist, braucht das für den Zugriff 
auf die Members des Zeigers nicht nochmal separat mit sowas wie -> 
ausgewiesen zu werden, ein schlichter Punkt reicht aus - und das 
vereinheitlicht die Syntax.

Ob man dabei wie in Pascal auch noch den Zeiger als solchen kennzeichnen 
soll ( POIN^.X := 14; ) oder ob man das wegläßt, weil es ja ohnehin klar 
ist, daß da ein Zeigerzugriff fällig ist, sei mal dahingestellt.


Bernd K. schrieb:
> fn foo(x: i32) -> i32

Das wiederum ist unsystematisch und führt nur zu Verwicklungen.
Immerhin wäre das Generalschema so:
typ
 bezeichner : typbeteichnung;

und da fällt eben auch eine Funktion darunter:
 function bezeichner < argumentdeklaration >  < : typbezeichnung > ;

also
 // eine function mit Argument(en), aber void
 function angela (a: integer; b: sonstwas);

 // eine function, hier ohne Argumente
 function horst : boolean;

 // eine function mit allem
 function konrad (a: integer; b: sonstwas): string;

Kurzum, für die Typ-Deklaration einer Funktion eine Extrawurst per "->" 
zu braten, halte ich für unsystematischen Unfug.


Privatfrickler schrieb:
> Gerade die "Kosmetik" zwingt aber leidlich zum permanenten Umdenken und
> schafft somit unnötig zusätzliche Komplexität. Wenn fünf
> Programmiersprachen fünf verschiedene Symbole für Zuweisungen verwenden,
> dann hast du fünf-fachen Aufwand diese zu unterscheiden. Und es bleibt
> ja nicht bei diesem einen Umstand. Für den Vergleich gibt es dann
> vielleicht wieder fünf verschiedene Symbole. Für einen Zeiger nochmals
> fünf weitere Unterschiedlichkeiten. Vor lauter Symboljongliererei
> verbraucht man dann mehr Hirnschmalz das noch auseinanderzuhalten als
> sich dem eigentlichen Sinn der Programmiererei zuzuwenden.

DAS ist mMn. ein würdiges Schlußwort unter diese ganze fruchtlose 
Diskussion um Rust und andere einschlägige Eintagsfliegen.

W.S.

von W.S. (Gast)


Lesenswert?

Yalu X. schrieb:
> Const bedeutet in diesem Zusammenhang,...

Das ist erstens die Implikation, daß eine jegliche Konstante 
grundsätzlich in einer Variablen gehalten werden muß. Also auch die 
Konstanten, die ansonsten direkt in den Code eingebaut wären.

Das ist zweitens ein Hinweis darauf, daß CONST in anderen Zusammenhängen 
eben andere Bedeutungen hat. Also ist das Ganze nur eine 
Verkomplizierung der Sprache - genauso wie z.B. der Asterisk in C.

Die Lösung all dieser unseligen Verkomplizierungen sind Konstanten und 
typisierte Konstanten.

const
// normale Konstante OHNE Typangabe
  A = 100;
// typisiert, also in Form einer vorbelegten Variable
  B : integer = 100;

Das ist für jeden Programmierer weitaus klarer und übersichtlicher als 
das Herumgeeiere bei Rust.

W.S.

von Bernd K. (prof7bit)


Lesenswert?

W.S. schrieb:
> Yalu X. schrieb:
>> Bist du sicher, dass deine Vision der optimalen Programmierpsrache ein
>> Vorbrenner für C ist, der fast genauso aussieht und nur ein wenig
>> unübersichtlicher ist? ;-) SCNR
>
> gröhl...
>
> Erstens ist es keineswegs meine Vision einer optimalen
> Programmiersprache, denn die war und ist schlichtweg Pascal.
>
> Zweitens ist das, was ich beschrieben habe, eine Renovierung von C

Du hast mein Posting also nicht gelesen in dem ich auf alle Deine Punkte 
einzeln eingegangen bin. Ich haben auch das Gefühl daß Du Dir Rust keine 
einzige Sekunde lang angesehen hast und einfach so blind drauf los 
polterst, sonst würdest Du nicht fortlaufend behaupten Rust hätte keinen 
der Fehler von C behoben denn alle (in Worten: ALLE) von Dir 
aufgezählten Wunscheigenschaften einer Sprache bzw Verbesserungen 
gegenüber C(++) sind in Rust auf höchst elegante Weise implementiert!

Und die Grammatik von Rust hat übrigens deutlich mehr Ähnlichkeit mit 
Pascal als mit C!

> meine Vision einer optimalen
> Programmiersprache, denn die war und ist schlichtweg Pascal.

Dir gefällt also Pascal besser als C oder C++, das ist verständlich, mir 
geht es genauso. Aber Rust ist das bessere Pascal! Du behauptest Rust 
erreicht das nicht? Dann erklär also bitte mal was die letzten 
verbliebenen Vorteile von Pascal gegenüber Rust sein sollen und zwar an 
konkreten Beispielen (mit Code den man vergleichen kann).

Die konkrete Schreibweise von Schlüsselworten, Operatoren oder sonstigen 
Syntaxelementen, also sowas wie & statt @ oder = statt := oder {} statt 
begin end oder fn statt function oder struct statt record lass ich NICHT 
gelten, das ist reine Kosmetik, dadurch wird eine Sprache kein bisschen 
besser oder schlechter, es geht um die Grammatik und um die 
Eigenschaften der Sprache und die Eigenschaften des Typsystems und 
welche konkreten Vor- und Nachteile die bringen.

So leid es mir tut, aber da mußt Du jetzt leider entweder endlich etwas 
tiefer einsteigen um eine sinnvolle Antwort formulieren zu können oder 
Du mußt sagen "Sorry, ich hab keine Ahnung von Rust, ich kann also nicht 
das geringste zu der ganzen Diskussion beitragen" und dann in diesem 
Thread von Schreib- auf Lesemodus umschalten!

Ich erwarte eine sinnvolle Antwort erst in 7 Tagen, lass Dir also die 
Zeit die Du brauchst. Eine Woche sollte reichen um einen groben 
Überblick über die Eigenschaften von Rust zu bekommen und es einschätzen 
zu können.

Du kannst auch ablehnen. Ich kann durchaus verstehen daß man keinen Bock 
hat sich eine neue Sprache genauer anzuschauen wenn man schon alles hat 
was man in der Praxis braucht oder zu brauchen glaubt. ABER dann 
poltert man nicht wie ein Volltrottel drauf los und stellt dümmliche 
Falschbehauptungen über irgendwelche Eigenschaften der vollkommen 
unbekannten Sprache auf sondern hält entweder einfach mal die Klappe und 
liest das was andere Leute zu sagen haben die sich zumindest mal ein 
paar Tage lang damit befasst haben oder man stellt sinnvolle Fragen und 
wertet die Antworten aus.

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


Lesenswert?

Yalu X. schrieb:
> Lass mich mal zusammenfassen:

Ich fasse das mal zusammen: Du siehst den Wald vor Bäumen nicht und 
liebäugelst sehr leicht mit Verkomplizierungen und Hakeligkeiten in 
Programmiersprachen. Die regen dein Interesse an. Das war schon früher 
dein Hobby, jaja, ich weiß, denn ich erinnere mich dran und es ist dir 
unbenommen. Schließlich haben wir alle unsere Hobbies - und die sind 
höchst unterschiedlich.

Und nein, Bernd hat lediglich einige meiner Renovierungspunkte für C 
kommentiert. Das ist ein himmelweiter Unterschied zu Rust und ich bin 
mit seinen Kommentaren z.T. überhapt nicht einverstanden.

Ich hatte nicht ohne Grund weiter oben sinngemäß geschrieben, daß man 
die Qualität einer neuen Programmiersprache durchaus daran messen kann, 
ob deren Erfinder sie auf saubere Art per BNF oder einer anderen ebenso 
strengen Darstellung zu beschreiben in der Lage sind.

Das trifft für Rust nicht zu - und wie auch du hättest sehen können in 
diesem Thread, ist Rust noch unsystematischer und mit noch mehr Wenn's 
und Aber's gespickt als C. Rust ist eine Verkomplizierung von C und 
keine Verbesserung, geschweige denn eine Renovierung oder gar ein 
besserer Ersatz für C. Es ist eine Wurschtelsprache.

Und jetzt bin ich's leid.

W.S.

von Bernd K. (prof7bit)


Lesenswert?

W.S. schrieb:
> Yalu X. schrieb:
>> Lass mich mal zusammenfassen:
>
> Ich fasse das mal zusammen: Du siehst den Wald vor Bäumen nicht

Nein, Yalu hat in wenigen Zeilen Deinen Widerspruch glasklar auf den 
Punkt gebracht, jeder kann es sehen und Dir fällt jetzt kein Weg mehr 
ein Dich da rauszuwinden.

Die einzige gültige Aussage Deinerseits wäre jetzt: "Sorry, sieht so aus 
als hätte ich totalen inkoherenten Bullshit verzapft. Ich nehme alles 
zurück."

von Yalu X. (yalu) (Moderator)


Lesenswert?

W.S. schrieb:
> Wenn man es überhaupt zuläßt, Typ- Konstanten- oder
> Variablendeklarationen innerhalb des Codes zuzulassen, dann öffnet das
> den Freiraum für Pfusch, was wir ja deutlichst in C bisher gesehen
> haben.

Nein, ganz im Gegenteil: Das dient dazu, den Scope einzuschränken.

In früheren Basic-Dialekten hatten alle Veriable globalen Scope, was
sich als schlecht herausstellte, da man bei globalen Variablen nicht
leicht erkennen kann, wo sie überall verändert werden. Also wurden
funktionslokale Variablen eingeführt, wie auch Pascal sie kennt. C (und
die meisten neueren Sprachen) erweitern dieses Prinzips auf blocklokale
Variablen, die zusätzliche Vorteile bieten:

- Der Scope wird weiter eingeschränkt, was vor allem bei größeren
  Funktionen zum Tragen kommt.

- Eine Variable kann genau an der Stelle angelegt werden, wo sie auch
  mit einem sinnvollen Wert initialisiert werden kann. Dadurch werden
  uninitalisierte Variablen und Pseudoinitialisierungen mit sinnlosen
  Dummy-Werten vermieden.

> Bernd K. schrieb:
>> fn foo(x: i32) -> i32
>
> Das wiederum ist unsystematisch und führt nur zu Verwicklungen.
> Immerhin wäre das Generalschema so:
> typ
>  bezeichner : typbeteichnung;
>
> und da fällt eben auch eine Funktion darunter:
>  function bezeichner < argumentdeklaration >  < : typbezeichnung > ;
>
> also
>  // eine function mit Argument(en), aber void
>  function angela (a: integer; b: sonstwas);
>
>  // eine function, hier ohne Argumente
>  function horst : boolean;
>
>  // eine function mit allem
>  function konrad (a: integer; b: sonstwas): string;
>
> Kurzum, für die Typ-Deklaration einer Funktion eine Extrawurst per "->"
> zu braten, halte ich für unsystematischen Unfug.

Ist es aber nicht, denn : und -> haben zwei völlig verschiedene
Bedeutungen:

... :  t bedeutet: ... ist                  vom Typ t.
... -> t bedeutet: ... liefert ein Ergebnis vom Typ t.

Dass in Pascal beide Sachverhalte gleich notiert werden, reduziert zwar
etwas die Zahl der vom Compiler zu parsenden Tokens, aber logisch
konsistent ist das definitiv nicht.

von Yalu X. (yalu) (Moderator)


Lesenswert?

W.S. schrieb:
> Und jetzt bin ich's leid.

Es ist ja völlig in Ordnung, dass Pascal für dich die optimale
Programmiersprache darstellt. Es ist auch völlig in Ordnung, wenn du
dich nicht mit anderen Sprachen beschäftigen möchtest, weil dir dazu die
Zeit oder die Lust fehlt.

Nur solltest du dann in Diskussionen über alternative Sprachen etwas
zurückhaltender sein.

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Hallo Yalu,

ich möchte noch kurz anmerken, dass ich deine Geduld in der 
const-Diskussion oben sehr bewundert habe. Ich bin hier schon wie ein 
Rumpelstilzchen auf und ab gehüpft, während Du Dein const-Zen 
durchgezogen hast.

Vorbildlich!

Herzliche Grüße

 Timm

von Karl K. (karl2go)


Lesenswert?

Bernd K. schrieb:
> also sowas wie & statt @ oder = statt := oder {} statt
> begin end oder fn statt function oder struct statt record lass ich NICHT
> gelten, das ist reine Kosmetik, dadurch wird eine Sprache kein bisschen
> besser oder schlechter

Ähm: Doch!

Eine Hochsprache sollte für den Programmierer gut lesbar sein, und da 
stinken die C-Derivate - wozu ich auch JS... zähle - mit ihren {(}{)} 
Mischmasch regelmäßig ab. Nicht so sehr beim Schreiben, vor allem beim 
Lesen von fremden oder älteren eigenen Code bekomm ich da regelmäßig 
Augenkrebs.

Schlechte Kosmetik ist ein Argument gegen eine Programmiersprache.

von Carl D. (jcw2)


Lesenswert?

Ja die vielen Sonderzeichen. Statt "x=y/z" ist doch "DIVIDE y BY z 
GIVING x" um so viel klarer in der Aussage.

von Alex G. (dragongamer)


Lesenswert?

Karl K. schrieb:
> Schlechte Kosmetik ist ein Argument gegen eine Programmiersprache.
Naja, Sache ist allerdings dass dies Gewöhnungssache ist.
Ich benutze auch hauptsächlich Sprachen mit{ und }. Wenn ichd ann mal 
Python code lesen muss, mit seinem BEGIN Kram, ist das extrem 
anstrengend und unübersichtlich...

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Alex G. schrieb im Beitrag #5526641
> Python code lesen muss, mit seinem BEGIN Kram, ist das extrem
> anstrengend und unübersichtlich...

hmm, könnte mir mal kurz jemand auf die Sprünge helfen? Bis betzt dacht 
ich, ich könnte Python ein wenig, aber scheinbar ist mir da etwas 
entgangen? Oder gibt es jetzt neuerdings inline Pascal in Python?

Viele liebe Grüße
Timm

von Privatfrickler (Gast)


Lesenswert?

Vincent H. schrieb:
> Privatfrickler schrieb:
>> Da habe ich auch noch einen gefunden
>>
>> https://hackernoon.com/why-im-dropping-rust-fd1c32...
>
> Nachdem du offensichtlich nicht einmal verstehst warum const wichtig ist

Da bist du im Irrtum. Ich habe halt eine eigene Vorstellung davon was 
sich const nennen sollte und was nicht. Im übrigen ging es in dem 
Beispiel um eine mir völlig fremde und somit neue Programmiersprache, 
die sich ziglang nennt und die ein paar Fragen für mich aufwarf. Ich 
habe nicht vor nun zu dieser weitgehend unbekannten Programmiersprache 
umzuschwenken. Dazu fehlt mir die Zeit und auch schlicht die Lust.

Im übrigen wurde das geklärt.

> oder dich mit der Lappalie der Wortwahl herumschlägst kann ich mir nicht
> vorstellen dass du auch nur eines der angesprochenen Probleme aus dem
> Link verstehst...

Du kannst dir wohl einiges nicht vorstellen. Brauchst du auch nicht. Das 
interessiert hier nämlich keinen, was DU dir vorstellen kannst oder 
nicht.

von Alex G. (dragongamer)


Lesenswert?

Timm R. schrieb:
> Alex G. schrieb im Beitrag #5526641
>> Python code lesen muss, mit seinem BEGIN Kram, ist das extrem
>> anstrengend und unübersichtlich...
>
> hmm, könnte mir mal kurz jemand auf die Sprünge helfen? Bis betzt dacht
> ich, ich könnte Python ein wenig, aber scheinbar ist mir da etwas
> entgangen? Oder gibt es jetzt neuerdings inline Pascal in Python?
>
> Viele liebe Grüße
> Timm
Wenn du häufig python nutzst, empfindest du das sicherlich nicht so wie 
ich - genau darauf wollte ich ja hinaus.
Mein Gehirn hat sich darauf eingestellt, aus { und }, die Struktur zu 
bilden und das passiert intuitiv.
Bei BEGIN und END muss ich aktiv überlgen "ah, hier beginnt der Block, 
hier endet er".
Nur die Einrückung reicht auch irgendwie nicht für meine Intuition.

Inline Kram ist in der tat häufig unübersichtlicher, wobei das aber mehr 
am Schreiber liegt. In der Regel muss man es ja nicht wirklich in einer 
Zeile schreiben.

von Privatfrickler (Gast)


Lesenswert?

W.S. schrieb:
>> fn foo(x: i32) -> i32
>
> Das wiederum ist unsystematisch und führt nur zu Verwicklungen.
> Immerhin wäre das Generalschema so:
> typ
>  bezeichner : typbeteichnung;
>
> und da fällt eben auch eine Funktion darunter:
>  function bezeichner < argumentdeklaration >  < : typbezeichnung > ;
>
> also
>  // eine function mit Argument(en), aber void
>  function angela (a: integer; b: sonstwas);
>
>  // eine function, hier ohne Argumente
>  function horst : boolean;
>
>  // eine function mit allem
>  function konrad (a: integer; b: sonstwas): string;
>
> Kurzum, für die Typ-Deklaration einer Funktion eine Extrawurst per "->"
> zu braten, halte ich für unsystematischen Unfug.

Kann ich gut nachvollziehen. Es drängt sich der Eindruck auf, hier 
teilen sich die Vorstellungen der Beteiligten. Die einen sind 
anscheinend ganz verpicht darauf neue Extrawürste serviert zu bekommen, 
nach dem Motto, öfter mal was neues, das alte kennen wir bereits zu gut, 
wird langweilig. Und die anderen sehen daran mehr Verdruss als 
wirklichen Nutzen.

W.S. schrieb:
> Yalu X. schrieb:
>> Lass mich mal zusammenfassen:
>
> Ich fasse das mal zusammen: Du siehst den Wald vor Bäumen nicht und
> liebäugelst sehr leicht mit Verkomplizierungen und Hakeligkeiten in
> Programmiersprachen. Die regen dein Interesse an. Das war schon früher
> dein Hobby, jaja, ich weiß, denn ich erinnere mich dran und es ist dir
> unbenommen. Schließlich haben wir alle unsere Hobbies - und die sind
> höchst unterschiedlich.

Ich glaube der Kernsatz ist "Die regen dein Interesse an". Vielleicht 
liegt dem geistige Unterauslastung zugrunde, ausgeprägter Spieltrieb, 
Langeweile oder eine Kombination aus all dem. Andere haben halt noch 
andere Neigungen und vor allem Prioritäten. Die Zeit, die man für A 
aufwendet fehlt bei B und umgekehrt.

von Bernd K. (prof7bit)


Lesenswert?

Alex G. schrieb:
> Wenn du häufig python nutzst, empfindest du das sicherlich nicht so wie
> ich - genau darauf wollte ich ja hinaus.
> Mein Gehirn hat sich darauf eingestellt, aus { und }, die Struktur zu
> bilden und das passiert intuitiv.
> Bei BEGIN und END muss ich aktiv überlgen "ah, hier beginnt der Block,
> hier endet er".

Du verstehst es nicht. es wurde durch die Blume angedeutet daß Du besser 
mal aufhörst irgendwelche Bemerkungen zu Python zu machen obwohl Du 
offensichtlich noch nie im Leben eine Zeile Python gesehen hast (und 
auch noch nie eine Sprache die begin und end verwendet).

Also nochmal, etwas direkter formuliert:

In Python gibts keine Blockmarkierungen durch begin end. Das ist eine 
andere Sprache. Die Tatsache daß Du die verwechselst sagt daß Du keine 
davon kennst, geschweige denn je damit praktisch gearbeitet hast, also 
bist Du per Definition nicht qualifiziert über deren praktische Vor- 
oder Nachteile auch nur den Hauch einer Aussage zu tätigen.

Verstehst Du es jetzt? Ist es Dir wenigstens ein ganz kleines bisschen 
peinlich?

von Privatfrickler (Gast)


Lesenswert?

Yalu X. schrieb:
>> Kurzum, für die Typ-Deklaration einer Funktion eine Extrawurst per "->"
>> zu braten, halte ich für unsystematischen Unfug.
>
> Ist es aber nicht, denn : und -> haben zwei völlig verschiedene
> Bedeutungen:
>
> ... :  t bedeutet: ... ist                  vom Typ t.
> ... -> t bedeutet: ... liefert ein Ergebnis vom Typ t.

Das ist doch die nächste Verwirrung. Wie willst du ein Ergebnis vom Typ 
i32 zurückliefern, ohne das in der Verpackung einer i32 Variablen zu 
transportieren?

Als Pointer auf i32 vielleicht. Aber bestimmt nicht in einem Char.

> Dass in Pascal beide Sachverhalte gleich notiert werden, reduziert zwar
> etwas die Zahl der vom Compiler zu parsenden Tokens, aber logisch
> konsistent ist das definitiv nicht.

Und wie man sieht ist Rust hier auch kein Paradebeispiel für Klarheit. 
Intuition geht anders.

Beitrag #5526789 wurde von einem Moderator gelöscht.
von Privatfrickler (Gast)


Lesenswert?

Bernd K. schrieb:
> In Python gibts keine Blockmarkierungen durch begin end. Das ist eine
> andere Sprache. Die Tatsache daß Du die verwechselst sagt daß Du keine
> davon kennst, geschweige denn je damit praktisch gearbeitet hast, also
> bist Du per Definition nicht qualifiziert über deren praktische Vor-
> oder Nachteile auch nur den Hauch einer Aussage zu tätigen.

Naja, über den Unsinn bei Python mit seiner durch Einrückung erzwungenen 
Blockkennzeichnung wird auch heftigst und Kontrovers bestritten.

von Privatfrickler (Gast)


Lesenswert?

Karl K. schrieb:
> Eine Hochsprache sollte für den Programmierer gut lesbar sein, und da
> stinken die C-Derivate - wozu ich auch JS... zähle - mit ihren {(}{)}
> Mischmasch regelmäßig ab. Nicht so sehr beim Schreiben, vor allem beim
> Lesen von fremden oder älteren eigenen Code bekomm ich da regelmäßig
> Augenkrebs.
>
> Schlechte Kosmetik ist ein Argument gegen eine Programmiersprache.

Das sehe ich auch so.

Beitrag #5526826 wurde von einem Moderator gelöscht.
von Bernd K. (prof7bit)


Lesenswert?

Privatfrickler schrieb:
> Und wie man sieht ist Rust hier auch kein Paradebeispiel für Klarheit.
> Intuition geht anders.

Das kann man sehen wie man will. Ein Mathematiker würde sicherlich den 
Pfeil bevorzugen, das hat wahrscheinlich auch seine Wurzeln in Haskell.

Oder schau Dir mal diesen Schnipsel an:
1
fn add(x: i32, y: i32) -> i32 {
2
    x + y
3
}
4
5
fn sub(x: i32, y: i32) -> i32 {
6
    x - y
7
}
8
9
fn calc(f: fn(i32, i32) -> i32, x:i32, y: i32) -> i32 {
10
    f(x, y)
11
}
12
13
fn main() {
14
    let x = calc(add, 2, 3);
15
    let y = calc(sub, 2, 3);
16
17
    println!("{} {}", x, y);
18
}

Und dann ersetz mal -> durch : und erzähl mir daß es besser aussieht 
oder klarer wird. Das Gegenteil wäre der Fall.

von Bernd K. (prof7bit)


Lesenswert?

Privatfrickler schrieb:
> Naja, über den Unsinn bei Python mit seiner durch Einrückung erzwungenen
> Blockkennzeichnung wird auch heftigst und Kontrovers bestritten.

Nur von denen die es nicht selbst benutzen, also von denen die 
eigentlich gar nicht wissen worüber sie schwafeln. Alle anderen sind 
glücklich darüber weil es so viel besser und einfacher zu handhaben ist.

von Bernd K. (prof7bit)


Lesenswert?

Privatfrickler schrieb:
> Das sehe ich auch so.

Kannst Du Dich nicht entscheiden? { } ist schlecht, kein { } ist auch 
schlecht, ja was denn nun?

Beitrag #5526854 wurde von einem Moderator gelöscht.
Beitrag #5526871 wurde von einem Moderator gelöscht.
Beitrag #5526900 wurde von einem Moderator gelöscht.
Beitrag #5526910 wurde von einem Moderator gelöscht.
Beitrag #5526916 wurde von einem Moderator gelöscht.
Beitrag #5526921 wurde von einem Moderator gelöscht.
von Karl K. (karl2go)


Lesenswert?

Privatfrickler schrieb:
> Naja, über den Unsinn bei Python mit seiner durch Einrückung erzwungenen
> Blockkennzeichnung wird auch heftigst und Kontrovers bestritten.

Sollte man meinen. Aber mir haben schon Pythonianer erklärt, dass das 
ganz toll ist. Die Foren sind zwar voll von Leuten, die rumjammern weil 
ihr Phython-Script nicht geht, und am Ende kommt raus, dass sie mal 
wieder beim Rumkopieren Leerzeichen und Tabs gemischt haben. Aber nee, 
Blöcke allein durch Einrückung ist ganz toll.

von Bernd K. (prof7bit)


Lesenswert?

Karl K. schrieb:
> Die Foren sind zwar voll von Leuten, die rumjammern weil
> ihr Phython-Script nicht geht, und am Ende kommt raus, dass sie mal
> wieder beim Rumkopieren Leerzeichen und Tabs gemischt haben. Aber nee,
> Blöcke allein durch Einrückung ist ganz toll.

Ja, ist es, und in der Praxis auch vollkommen problemlos. Und es fühlt 
sich sehr angenehm an. Gäbe es auch nur die geringsten Probleme damit 
wären sie mir schon aufgefallen, ich verbringe immerhin 8 Stunden jeden 
Tag mit Python.

In diesem Thread gehts aber um Rust und nicht um Python oder Haskell 
oder andere Sprachen mit offside-rule, Rust hat geschweifte Klammern und 
seit wann sind in diesem Forum neuerdings geschweifte Klammern verpöhnt 
und kaum ist die Abneigung gegen die Klammern ausgesprochen wird gegen 
die Abwesenheit derselben in anderen Sprachen auch wieder gewettert - 
von den selben Leuten!? Könnt ihr euch mal alle entscheiden für oder 
gegen was ihr seid und könnte man das Thema vielleicht wieder auf Rust 
zurücklenken?

Warum sehe ich zum Beispiel keine Diskussion über klassische 
OOP-Techniken vs Rust oder ähnliche hochexplosive Themen mit ultra 
Flamewar-Potential? DAS wäre vielleicht mal wirklich interessant, da 
könnte man vielleicht noch vereinzelte Perlen aus der Diskussion 
extrahieren aber warum müsst ihr euch stattdessen alle an solchem 
lächerlichen oberflächlichen Kleinkram der jenseits des Parsers schon 
gar nicht mehr existiert weil er so bedeutungslos ist hoch und 
runterziehen wie die bekloppten?

Das ist ja ungefähr so als ob man in größter Erregung schäumend vor Wut 
über den Sinn und die Zukunft von Elektrofahrzeugen streitet und das 
ganze allein am Fehlen des Kupplungspedals festmacht!

Liegts daran daß man dazu etwas tiefer einsteigen müsste in die Materie 
als mit "hello world"-Kenntnissen den selbsternannten 
Programmiersprachenexperten raushängen zu lassen? Liegts daran?

Langsam glaub ich echt der Fachkräftemangel ist real. Wenn dieses 
"Fachforum" in irgendeiner weise repräsentativ sein soll für die 
Insassen der hiesigen Industrieanstalten dann ist wirklich alles am 
Ende! Aber womöglich treffen sich hier auch nur die Ausgestoßenen, wenn 
ja wo gehts dann bitte zum richtigen Forum?

Beitrag #5527089 wurde von einem Moderator gelöscht.
Beitrag #5527093 wurde von einem Moderator gelöscht.
Beitrag #5527096 wurde von einem Moderator gelöscht.
Beitrag #5527348 wurde von einem Moderator gelöscht.
Beitrag #5527356 wurde von einem Moderator gelöscht.
Beitrag #5527358 wurde von einem Moderator gelöscht.
Beitrag #5527360 wurde von einem Moderator gelöscht.
Beitrag #5527361 wurde von einem Moderator gelöscht.
Beitrag #5527362 wurde von einem Moderator gelöscht.
Beitrag #5527363 wurde von einem Moderator gelöscht.
Beitrag #5527364 wurde von einem Moderator gelöscht.
Beitrag #5527365 wurde von einem Moderator gelöscht.
Beitrag #5527366 wurde von einem Moderator gelöscht.
Beitrag #5527367 wurde von einem Moderator gelöscht.
Beitrag #5527369 wurde von einem Moderator gelöscht.
Beitrag #5527371 wurde von einem Moderator gelöscht.
Beitrag #5527373 wurde von einem Moderator gelöscht.
Beitrag #5527374 wurde von einem Moderator gelöscht.
Beitrag #5527375 wurde von einem Moderator gelöscht.
Beitrag #5527376 wurde von einem Moderator gelöscht.
Beitrag #5527377 wurde von einem Moderator gelöscht.
Beitrag #5527379 wurde von einem Moderator gelöscht.
Beitrag #5527445 wurde von einem Moderator gelöscht.
von Bernd K. (prof7bit)


Lesenswert?

H. B. Reinhardt schrieb im Beitrag #5527364:
> Der Mod lässt eine Meinung wieder mal nicht gelten

Deine Meinung interessiert niemanden, auch nicht den Mod. Sie ist auch 
nicht relevant in diesem Thread weil sie nichts mit den Thema zu tun hat 
und auch sonst nichts zur Diskussion beiträgt. Du bettelst um Löschung 
und versuchst den Thread zu sabotieren.

Ich hoffe inständig daß bald eine automatische Filterlösung in Kraft 
gesetzt wird die den destruktiven Schwachsinn von asozialen Arschlöchern 
und Krawallbrüdern wie Dir schon löschen bevor er überhaut gespeichert 
wird so daß niemand mehr damit belästigt wird, noch nicht mal die Mods.

@Mods: ich würde das ganze Subnetz des Störers bis auf weiteres auf 
Login-Pflicht vor dem Posten setzen, der Kollateralschaden hält sich in 
Grenzen, lesenswerte Posts werden dadurch nicht behindert werden.

: Bearbeitet durch User
Beitrag #5527506 wurde von einem Moderator gelöscht.
Beitrag #5527507 wurde von einem Moderator gelöscht.
Beitrag #5527508 wurde von einem Moderator gelöscht.
Beitrag #5527509 wurde von einem Moderator gelöscht.
Beitrag #5527511 wurde von einem Moderator gelöscht.
Beitrag #5527514 wurde von einem Moderator gelöscht.
Beitrag #5527517 wurde von einem Moderator gelöscht.
Beitrag #5527522 wurde von einem Moderator gelöscht.
Beitrag #5527558 wurde von einem Moderator gelöscht.
Beitrag #5527565 wurde von einem Moderator gelöscht.
Beitrag #5527567 wurde von einem Moderator gelöscht.
Beitrag #5527568 wurde von einem Moderator gelöscht.
Beitrag #5527569 wurde von einem Moderator gelöscht.
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Bedankt Euch bei unserem kleinen gestörten Freund.

Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.