Von C zu Rust wechseln?



  • @NewHope
    Du solltest nicht von dir auf andere schliessen.

    Das Problem dabei grössere C++ Projekte leakfrei zu bekommen ist nicht dass die Sache ansich so schwer wäre, sondern dass man mit so vielen Leuten zusammenarbeiten muss die es nie richtig gelernt haben, nicht richtig machen wollen oder nicht richtig machen können weil sie einfach zu doof dafür sind. (Interessehalber: welche dieser Eigenschaften ist es bei dir?)

    Im übrigen der selbe Grund warum grössere Projekte in anderen Sprachen auch nicht ordentlich hinhauen. Selbst in GC-Sprachen kann man schön Leaks bauen. Und Leaks sind ja auch nicht die einzige Fehlerkategorie unter der grössere Projekte öfter mal leiden.



  • Es tut mir Leid, aber wenn jemand von sich behauptet, hinsichtlich Speicherfehler, nie einen Fehler zu übersehen, dann glaube ich das halt nicht. Niemand entwickelt zu 100% sicher. Wenn dies tatsächlich mal jemanden gelingen sollte, dann sorgen andere Aspekte dafür, das Speicherfehler da rein kommen, von denen du ja einige genannt hast. Genau deswegen ist es doch ein genial, wenn eine Sprache diese Fehler zur Compilezeit mit Zero-Costs und ohne GC zu 100% eliminieren kann und genau das macht Rust.



  • NewHope schrieb:

    Es tut mir Leid, aber wenn jemand von sich behauptet, hinsichtlich Speicherfehler, nie einen Fehler zu übersehen, dann glaube ich das halt nicht.

    Behauptet auch keiner. Der erste Build crasht sehr häufig. Dann schmeiß ich den Debugger an, warte bis zur Debug Assertion, schau mir den Callstack und Locals an, facepalme und fixe ihn. Selten brauche ich aber auch länger.

    Niemand entwickelt zu 100% sicher. Wenn dies tatsächlich mal jemanden gelingen sollte, dann sorgen andere Aspekte dafür, das Speicherfehler da rein kommen, von denen du ja einige genannt hast.

    Das behauptet auch keiner. Aber ich persönlich kenne keine Releaseversion irgendeiner guten Bibliothek, die Speicherfehler hat, wenn ich sie richtig verwende. Keine einzige.

    Genau deswegen ist es doch ein genial, wenn eine Sprache diese Fehler zur Compilezeit mit Zero-Costs und ohne GC zu 100% eliminieren kann und genau das macht Rust.

    Ja, das spart einem die 10 Minuten Debugging.

    Rust ist aber trotzdem nicht per se sicher und C++ per se unsicher. Das ist einfach nur extremer Schwachsinn.



  • Man braucht sie nicht übersehen - wer den richtigen Programmierstil hat der baut per Design keine Speicherfehler. Möchte ich etwas exklusiv besitzen dann kopiere oder move ich es. Möchte ich es teilen dann verwende ich shared_ptr oder eine zentrale Verwaltungsinstanz mit garantierter Lebenszeit.



  • So ein Unsinn und wie entstehen die ganzen Speicherfehler dann? Sie entstehen weil man eben nicht immer auf alles achten kann.



  • NewHope schrieb:

    So ein Unsinn und wie entstehen die ganzen Speicherfehler dann? Sie entstehen weil man eben nicht immer auf alles achten kann.

    Was heißt hier ganzen Speicherfehler?
    Wie häufig sind denn deiner Meinung nach, Speicherfehler in fertigen C++ Projekten?



  • NewHope schrieb:

    So ein Unsinn und wie entstehen die ganzen Speicherfehler dann? Sie entstehen weil man eben nicht immer auf alles achten kann.

    Nein, weil die Leute keine Ahnung von (modernem) C++ zu haben. Man muss nicht auf alles achten sondern einfach nur grobe Fehler vermeiden.



  • hustbaer schrieb:

    Das Problem dabei grössere C++ Projekte leakfrei zu bekommen ist nicht dass die Sache ansich so schwer wäre, sondern dass man mit so vielen Leuten zusammenarbeiten muss die es nie richtig gelernt haben, nicht richtig machen wollen oder nicht richtig machen können weil sie einfach zu doof dafür sind.

    Genau, einerseits erlaubt C++ "falsches" Memory-Handling und die "doofen" Leute lernen nie, wie man es richtig macht, andererseits hat man in C++ Kommunikationsfehler bezüglich Ownership (Schnittstellen nicht ausreichend/korrekt dokumentiert). Mit unique_ptr/shared_ptr geht zwar vieles, aber selbst damit kann es zu Fehlern kommen.

    Beide Fehler passieren in Rust nicht.

    Bez. dem C++-Getrolle:

    Ethon schrieb:

    Man braucht sie nicht übersehen - wer den richtigen Programmierstil hat der baut per Design keine Speicherfehler.

    Ethon schrieb:

    weil die Leute keine Ahnung von (modernem) C++ zu haben. Man muss nicht auf alles achten sondern einfach nur grobe Fehler vermeiden.

    Klar kann man kleinere Ein-Mann-Projekte mit genügend Hingabe korrekt umsetzen. Es passieren halt auch wenig Kommunikationsfehler. Fakt ist, dass in C++ die Schnittstellen mit Sprachmitteln nicht hinreichend dokumentiert werden können. Eine zweite Persion hätte da aber grosse Schwierigkeiten durchzublicken.

    Nathan schrieb:

    Wie häufig sind denn deiner Meinung nach, Speicherfehler in fertigen C++ Projekten?

    Segfaults in clang und g++ sind während der Entwicklung nicht selten. Und die kriegt man nur durch mühsames Debuggen wieder raus.
    Beide Projekte müssten doch von Leuten programmiert sein, die nicht "doof" sind oder "keine Ahnung von C++ haben".

    Und ich möchte betonen, dass Speichersicherheit nicht nur mit Leaks/Double frees/Nullpointer-Dereferenzierungen/Dangling references/etc. zu tun hat, sondern auch mit Data-Races.



  • müssen schrieb:

    Nathan schrieb:

    Wie häufig sind denn deiner Meinung nach, Speicherfehler in fertigen C++ Projekten?

    Segfaults in clang und g++ sind während der Entwicklung nicht selten. Und die kriegt man nur durch mühsames Debuggen wieder raus.

    Richtig, während der Entwicklung. Nicht im fertigem Code.
    Oder meinste von Clang und GCC selber?

    Beide Projekte müssten doch von Leuten programmiert sein, die nicht "doof" sind oder "keine Ahnung von C++ haben".

    Nein. Die internal compiler errors sind idR nur bei sehr obskuren, neuen C++ Features. Die Implementierung ist dann natürlich nicht ausgereift, da passiert sowas.

    Und ja, in Rust ist das wohl schwerer bis nahezu unmöglich, so Fehler zu machen. Ist ja auch schön und gut. Aber stellt bitte nicht C++ so dar, dass dort zwangsläufig Fehler passieren müssen.

    Und ich möchte betonen, dass Speichersicherheit nicht nur mit Leaks/Double frees/Nullpointer-Dereferenzierungen/Dangling references/etc. zu tun hat, sondern auch mit Data-Races.

    Zu Data-Races hab ich kaum Erfahrung, kann da nichts zu sagen.

    Edit:

    müssen schrieb:

    hustbaer schrieb:

    Das Problem dabei grössere C++ Projekte leakfrei zu bekommen ist nicht dass die Sache ansich so schwer wäre, sondern dass man mit so vielen Leuten zusammenarbeiten muss die es nie richtig gelernt haben, nicht richtig machen wollen oder nicht richtig machen können weil sie einfach zu doof dafür sind.

    Genau, einerseits erlaubt C++ "falsches" Memory-Handling und die "doofen" Leute lernen nie, wie man es richtig macht.

    Rust erlaubt auch "falsches" Memory Handling in unsafe Blöcken. Und das Problem ist ja, dass es sich die "doofen" Leute zutrauen, mit rohen Pointern/in unsafe Blöcken zu arbeiten und das deshalb auch tun werden. "doofe" Programmierer werden immer Speicherfehler produzieren, egal welche Sprache.



  • Nein, der gcc ist nicht representativ für schönes C.
    Hier ein 50+ Zeilen if Statement:

    if (in != 0 && GET_CODE (in) == SUBREG
          && (subreg_lowpart_p (in) || strict_low)
    #ifdef CANNOT_CHANGE_MODE_CLASS
          && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (in)), inmode, rclass)
    #endif
          && contains_reg_of_mode[(int) rclass][(int) GET_MODE (SUBREG_REG (in))]
          && (CONSTANT_P (SUBREG_REG (in))
    	  || GET_CODE (SUBREG_REG (in)) == PLUS
    	  || strict_low
    	  || (((REG_P (SUBREG_REG (in))
    		&& REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER)
    	       || MEM_P (SUBREG_REG (in)))
    	      && ((GET_MODE_PRECISION (inmode)
    		   > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in))))
    #ifdef LOAD_EXTEND_OP
    		  || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
    		      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
    			  <= UNITS_PER_WORD)
    		      && (GET_MODE_PRECISION (inmode)
    			  > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in))))
    		      && INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (in)))
    		      && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (in))) != UNKNOWN)
    #endif
    #ifdef WORD_REGISTER_OPERATIONS
    		  || ((GET_MODE_PRECISION (inmode)
    		       < GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in))))
    		      && ((GET_MODE_SIZE (inmode) - 1) / UNITS_PER_WORD ==
    			  ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - 1)
    			   / UNITS_PER_WORD)))
    #endif
    		  ))
    	  || (REG_P (SUBREG_REG (in))
    	      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
    	      /* The case where out is nonzero
    		 is handled differently in the following statement.  */
    	      && (out == 0 || subreg_lowpart_p (in))
    	      && ((GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
    		   && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
    		       > UNITS_PER_WORD)
    		   && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
    			/ UNITS_PER_WORD)
    		       != (int) hard_regno_nregs[REGNO (SUBREG_REG (in))]
    						[GET_MODE (SUBREG_REG (in))]))
    		  || ! HARD_REGNO_MODE_OK (subreg_regno (in), inmode)))
    	  || (secondary_reload_class (1, rclass, inmode, in) != NO_REGS
    	      && (secondary_reload_class (1, rclass, GET_MODE (SUBREG_REG (in)),
    					  SUBREG_REG (in))
    		  == NO_REGS))
    #ifdef CANNOT_CHANGE_MODE_CLASS
    	  || (REG_P (SUBREG_REG (in))
    	      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
    	      && REG_CANNOT_CHANGE_MODE_P
    	      (REGNO (SUBREG_REG (in)), GET_MODE (SUBREG_REG (in)), inmode))
    #endif
    	  ))
    

    https://github.com/gcc-mirror/gcc/blob/7057506456ba18f080679b2fe55ec56ee90fd81c/gcc/reload.c#L1056-L1110



  • Ethon schrieb:

    Nein, der gcc ist nicht representativ für schönes C.

    Darum habe ich auch clang zuerst genannt.

    Hier ein 50+ Zeilen if Statement:

    Wie hättest du es denn anders gemacht? Bzw. wieso würde das bei dir nicht vorkommen?

    Nathan schrieb:

    Beide Projekte müssten doch von Leuten programmiert sein, die nicht "doof" sind oder "keine Ahnung von C++ haben".

    Nein. Die internal compiler errors sind idR nur bei sehr obskuren, neuen C++ Features. Die Implementierung ist dann natürlich nicht ausgereift, da passiert sowas.

    Genau das meine ich doch! Die Entwicklung ist nicht ausgereift => Segfault. Wieso Segfault? Weil irgendwo Speicherfehler passiert sind. (Oder durch null dividiert, aber das ist recht selten.) Wie fixen? Stundenlang vor dem Debugger sitzen und alle mögliche Eingaben ausprobieren. Dann kommen so Weisheiten zustande wie "80% der Zeit sitzt man vor dem Debugger".

    In Rust würde das nicht passieren, weil der Compiler das garantiert.

    Nathan schrieb:

    Rust erlaubt auch "falsches" Memory Handling in unsafe Blöcken. Und das Problem ist ja, dass es sich die "doofen" Leute zutrauen, mit rohen Pointern/in unsafe Blöcken zu arbeiten und das deshalb auch tun werden. "doofe" Programmierer werden immer Speicherfehler produzieren, egal welche Sprache.

    Ich habe da andere Erfahrung gemacht. unsafe ist unelegant und kein Programmierer will uneleganten Code schreiben. Ausserdem reduziert sich der Code, in dem man Speicherfehler suchen muss auf unsafe-Blöcke.
    Wobei ich das nicht mit 100% Sicherheit sagen kann, da vielleicht noch gar keine doofen Programmierer nach Rust gekommen sind.



  • Typischer Fall von write once read never.



  • Dass reload.c fürchterlich ist weiß im gcc Team auch jeder. Der gcc ist einfach uralt und zu einem Monster gewachsen. Deswegen ist clang im Vergleich auch so fit und die Entwicklung geht schneller und besser voran.



  • müssen schrieb:

    Nathan schrieb:

    Beide Projekte müssten doch von Leuten programmiert sein, die nicht "doof" sind oder "keine Ahnung von C++ haben".

    Nein. Die internal compiler errors sind idR nur bei sehr obskuren, neuen C++ Features. Die Implementierung ist dann natürlich nicht ausgereift, da passiert sowas.

    Genau das meine ich doch! Die Entwicklung ist nicht ausgereift => Segfault. Wieso Segfault? Weil irgendwo Speicherfehler passiert sind. (Oder durch null dividiert, aber das ist recht selten.) Wie fixen? Stundenlang vor dem Debugger sitzen und alle mögliche Eingaben ausprobieren. Dann kommen so Weisheiten zustande wie "80% der Zeit sitzt man vor dem Debugger".

    Laut meiner Erfahrung ist das Debuggen nicht so lang, idR finde ich die Ursache für meine (seltenen) Segfaults recht schnell.

    In Rust würde das nicht passieren, weil der Compiler das garantiert.

    Ja. In C++ garantiert er das leider nicht. Ich wollte lediglich gegen die Haltung von einigen, dass C++ nur unsicheren Code hat, argumentieren.

    Nathan schrieb:

    Rust erlaubt auch "falsches" Memory Handling in unsafe Blöcken. Und das Problem ist ja, dass es sich die "doofen" Leute zutrauen, mit rohen Pointern/in unsafe Blöcken zu arbeiten und das deshalb auch tun werden. "doofe" Programmierer werden immer Speicherfehler produzieren, egal welche Sprache.

    Ich habe da andere Erfahrung gemacht. unsafe ist unelegant und kein Programmierer will uneleganten Code schreiben. Ausserdem reduziert sich der Code, in dem man Speicherfehler suchen muss auf unsafe-Blöcke.
    Wobei ich das nicht mit 100% Sicherheit sagen kann, da vielleicht noch gar keine doofen Programmierer nach Rust gekommen sind.

    Dasselbe gilt auch für Smartpointer und trotzdem nutzen manche rohe Pointer. Sie werden auch aus demselben Grund unsafe Blöcke verwenden.



  • Gute Nachrichten, meine Arbeitssituation hat sich geändert. Ich werde wohl nie mehr auch nur eine Zeile Code schreiben. Das bedeutet ihr könnt weiter an die vielen 100% speichersicheren C++-Projekte glauben, wovon ich nicht ein einziges kenne. Bei Rust ist das einfach, alles was nicht in einem unsafe Block ist, ist sicher.

    C++ ist ein einziger unsafe Block...arme IT-Welt wenn das so bleibt.

    Also von mir dann alles Gute, bye bye.



  • Eine Aussage in der Richtung „in einem C++-Programm gibt es immer Speicherfehler“ sollte man werten wie „in einem PHP-Programm gibt es immer Sicherheitslücken“. Selbstverständlich ist das absolut gesehen falsch, das heißt aber nicht, dass es nicht bestimmte Tendenzen geben kann. Natürlich kann man eine PHP-Anwendung absolut sicher programmieren, aber wenn man auf Sicherheit Wert legt, sieht man sich vielleicht doch nach einer anderen Sprache um.

    Ich möchte die Aussage an sich nicht unterstreichen. Ich bin auch der Meinung, dass durch konsequente Anwendung von RAII und entsprechender Smartpointer in mehr als 90% der Fälle keine Speicherfehler entstehen, sondern nur in Randfällen, die in der Praxis selten auftauchen. Ich möchte aber darauf hinweisen, dass die entsprechenden Aussagen in Bezug auf C++ weniger absolut interpretiert werden sollten, als dass manche hier tun.

    Außerdem möchte ich bemerken, dass manche C++ hier mit Argumenten der Art „brauch ich nicht, passiert mir nicht“ verteidigen. Aber ungeachtet der vielen Gründe, die gegen einen Umstieg auf Rust sprechen, sollte man doch einsehen, dass in puncto Speichersicherheit Rust objektiv besser ist als C++. Selbst wenn es am Ende eine Gegenüberstellung ist von „verhindert 95% der Speicherfehler“ vs. „verhindert 99,9%“.



  • @NewHope
    Ich glaub ich hab dich auch falsch verstanden.
    Du hast "Speicherfehler" geschrieben und ich hab "Memory-Leaks" gedacht.

    Was andere Speicherfehler angeht, also z.B. die allseits beliebten Data-Races, ... also das fehlerfrei hinzubekommen ist schon nicht mehr so trivial. Wenn man weiss wie man es macht, aufpasst und ein wenig Glück hat hat man auch da gute Chancen ein grösseres Projekt halbwegs fehlerfrei hinzubekommen. Aber da würde ich mich nicht mehr zu behaupten trauen dass ich das automatisch und im Halbschlaf immer richtig mache. Fast immer, aber sicher nicht im Halbschlaf 😉

    Und ja, natürlich ist es eine gute Sache wenn die Sprache solche Dinge enforcen kann. Bzw. ist das zumindest meine Meinung. Mit der ich aber auch nicht ganz alleine bin. Carmack hat z.B. auf einer "seiner" letzten Quakecons in seiner Keynote erwähnt dass er gerne Tools hätte mit denen er viele zusätzliche Regeln enforcen kann (also diverse Coding-Guidelines, Regeln dieser Art).



  • Jo, kein Thema. Ach ich bin jetzt übrigens nur noch Anwender von Grafik und Audioprogrammen und habe daher nie wieder was mit Programmierung zu tun(Vielleicht mal ein Script, mehr aber nicht). Nach 10 Jahren in der Branche hatte ich einfach die Nase voll. Euch allen viel Spaß bei der Software-Entwicklung, mich hat sie letzten Endes doch nicht glücklich gemacht. Das was ich jetzt mache sieht und hört man sofort und kann es auch nicht ITlern zeigen. So was ist einfach schöner für mich.

    Also...machts gut.



  • An die C++ Verfechter: Kann mir mal jemand ein Chrome oder Mozilla Release zeigen, in denen keine Speicherfehler vorkommen? Bin gespannt! 🙂



  • Realität schrieb:

    An die C++ Verfechter: Kann mir mal jemand ein Chrome oder Mozilla Release zeigen, in denen keine Speicherfehler vorkommen? Bin gespannt! 🙂

    An dich: Kannst du bitte mal ein Rust Projekt zeigen, dass es besser hinbekommt?


Anmelden zum Antworten