Forum: Compiler & IDEs Rust als Embedded-Programmiersprache


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.

Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.