Warum nicht nicht verwalteten sicheren Code in C # verwenden?


10

In C # gibt es eine Option, um Code ohne Kontrolle auszuführen. Dies wird im Allgemeinen nicht empfohlen, da verwalteter Code viel sicherer ist und viele Probleme überwindet.

Ich frage mich jedoch, ob Sie sicher sind, dass Ihr Code keine Fehler verursacht und Sie wissen, wie Sie mit Speicher umgehen, warum (wenn Sie schnellen Code mögen) den allgemeinen Ratschlägen folgen?

Ich frage mich das, seit ich ein Programm für eine Videokamera geschrieben habe, das eine extrem schnelle Bitmap-Manipulation erfordert. Ich habe selbst einige schnelle grafische Algorithmen erstellt, die mit nicht verwaltetem Code hervorragend auf Bitmaps funktionieren.

Jetzt frage ich mich im Allgemeinen, ob Sie nicht häufiger nicht verwalteten Code verwenden, wenn Sie sicher sind, dass Sie keine Speicherlecks oder Absturzrisiken haben.

PS mein Hintergrund: Ich bin irgendwie in diese Programmierwelt gerollt und arbeite alleine (ich mache das seit ein paar Jahren) und hoffe, dass diese Frage zum Software-Design nicht so seltsam ist. Ich habe nicht wirklich andere Leute da draußen wie einen Lehrer, die solche Dinge fragen.


8
unsafebedeutet "wissen, was Sie tun, und den Nutzen gegen die Risiken abwägen." Ich habe unsafeein paar Mal verwendet, und es war immer für etwas sehr Spezifisches in Bezug auf die Leistung, das auf seine eigene Weise abgeschottet werden konnte. Ich verwende es nicht als allgemeine Programmiertechnik, da der zusätzliche Leistungsvorteil den Sicherheitsverlust meistens nicht wert ist.
Robert Harvey

14
Ich habe im Laufe der Jahre viel Code geschrieben, der manchmal abstürzte oder Speicherverluste aufwies. Ich war mir ziemlich sicher, dass er keine Speicherverluste oder Absturzrisiken hatte.
Whatsisname

1
Hier ist ein gutes unsafeAnwendungsbeispiel: stackoverflow.com/q/11660127/102937
Robert Harvey

3
Ich denke, Ihr Bitmap-Code hat immer noch Fehler, aber Sie haben sie einfach nicht erkannt. Und selbst wenn dies nicht der Fall ist, warten Sie, bis Sie einige neue Anforderungen in den vorhandenen Code implementieren müssen.
Doc Brown

1
Denn selbst wenn Sie sicher sind, dass Ihr Code keine Fehler verursacht, verursacht er dennoch Fehler.
user253751

Antworten:


27

Nun, es ist meistens ein Fall des uralten Sprichworts

  • Nicht optimieren
  • (nur für Experten) Noch nicht optimieren

Aber eigentlich kann ich mir drei Hauptgründe vorstellen, um unsicheren Code zu vermeiden.

  1. Bugs : Der kritische Teil Ihrer Frage ist „ wenn Sie sicher , dass Ihr Code sind wird nicht Ursache Fehler“. Wie können Sie absolut sicher sein? Haben Sie einen Prüfer mit formaler Methode verwendet, der garantiert, dass Ihr Code korrekt ist? Eines ist bei der Programmierung sicher, und das ist, dass Sie Fehler haben werden. Wenn Sie eine Sicherheit abnehmen, lassen Sie neue Arten von Insekten durchschleichen. Wenn Sie den Garbage Collector für Sie den Speicher übernehmen lassen, verschwinden viele Probleme.

  2. Nicht immer so schnell wie Sie denken : Der andere Punkt ist: Je nach Problem ist der Gewinn möglicherweise nicht so groß. Obwohl ich sie momentan nicht zu finden scheine, erinnere ich mich an eine Studie von Google, in der die Geschwindigkeit von Java, Scala, Go und C ++ verglichen wurde. Einmal auf den Boden optimiert, war C ++ natürlich viel schneller. Aber der auf "idiomatische" Weise programmierte Algorithmus war nicht wirklich viel schneller. Idiomatisch in dem Sinne, dass sie Standardstrukturen und Redewendungen verwendeten (stl-Container, keine entrollte Schleife usw.). Microsoft hat ein ähnliches Experiment mit C # und C ++ durchgeführt. Raymond Chen, einer der besten Microsoft-Ingenieure, musste seine eigene Implementierung von std :: string schreiben, um C # zu schlagen. (Siehe: http://www.codinghorror.com/blog/2005/05/on-managed-code-performance-again.html) Für viel weniger Aufwand haben Sie eine ziemlich anständige Leistung in verwaltetem Code, so dass sich die Mühe oft nicht lohnt.

  3. Wiederverwendbarkeit : Unsicherer Code kann nur in einer Umgebung mit vollständiger Vertrauenswürdigkeit verwendet werden. Beispielsweise können Sie auf einem ASP.NET-Server normalerweise keinen unsicheren Code verwenden, da es ziemlich einfach wäre, eine Sicherheitsanfälligkeit durch Pufferüberlauf einzuführen. Ein weiteres Beispiel wäre clickonce. Oder wenn auf Ihre Anwendung über eine Netzwerkfreigabe zugegriffen wurde. Wenn Sie also vorhaben, Ihren Code in verschiedenen Bereitstellungsszenarien zu verwenden, ist unsicherer Code nicht im Spiel.

Im Grunde genommen: Es ist verpönt, weil es unnötige Fehler verursachen kann, möglicherweise überhaupt keinen Gewinn bringt und die Wiederverwendbarkeit Ihres Codes verringert.

Wenn Ihr Szenario dies jedoch wirklich für die Leistung erfordert (und Sie Daten haben, um dies zu beweisen), sind Sie ein erfahrener Programmierer, der weiß, wie man mit Speicher umgeht, und Ihr Code wird in einer kontrollierten Umgebung verwendet.


4

In gewisser Weise ist nicht verwalteter Code eine Zahlungsmethode: Sie kaufen eine schnellere Ausführung mit dem zusätzlichen Entwicklungsaufwand. In der Tat benötigt der nicht verwaltete Code mehr Zeit zum Entwickeln, Debuggen und Verwalten. Für die meisten Teilnehmer ist es eine Herausforderung, es genau richtig zu machen. In gewisser Weise ähnelt dies der Programmierung in der Assembly: Sicher, Sie können mehr Leistung aus Ihrer CPU herausholen, wenn Sie in Assembly * schreiben , aber Sie "investieren" viel mehr Mühe in diese Richtung.

Manchmal ist der Unterschied in der Entwicklungszeit sehr bedeutend - Tage statt Stunden. Der Unterschied in der Ausführungsgeschwindigkeit ist jedoch bei weitem nicht so dramatisch. Aus diesem Grund ist die Entwicklung von nicht verwaltetem Code Situationen vorbehalten, die denen ähneln, die Sie in Ihrem Beitrag beschrieben haben - lokalisierte, in sich geschlossene Implementierungen ressourcenhungriger Algorithmen wie Audio- und Videoverarbeitung.

Im Wesentlichen ähnelt die Antwort auf Ihre Frage der Antwort, warum nicht jeder Ferrari fährt: Es ist ein viel besseres Auto, oder? (Un) zum Glück kann es sich nicht jeder leisten.


* Die Fortschritte der letzten Jahrzehnte in der Optimierungstechnologie bei Compilern haben diese Lücke so weit verringert, dass dies jedoch keine sichere Wette mehr ist.


0

Weil es für imperative Sprachen ein sehr schwieriges Problem ist, sich über Korrektheit oder andere Einschränkungen im mathematischen Sinne "sicher" zu sein (dh Sie haben Beweise). Programme haben oft eine so hohe Anzahl von Zuständen, dass es nicht möglich ist, sie zu überprüfen, selbst wenn jeder mögliche Zustand überprüft wird. Das Erstellen eines konstruktiven Beweises kann nicht automatisiert werden.

Der Grund dafür ist, dass die Versicherungen, die die verwaltete Ausführung bietet, den geringen Leistungsgewinn, den Sie mit unsicherem Code erzielen würden, am häufigsten übersteigen. Dies hängt natürlich auch vom jeweiligen Anwendungsfall ab.


1
Ich denke, es hat nichts mit Korrektheit oder Einfachheit der Vernunft zu tun.
Jimmy Hoffa

Niemand spricht von einem formalen Beweis der Richtigkeit.

1
Ich bin mir sicher, dass Ihr Beitrag den Punkt verfehlt, aber ich formuliere keinen formellen Beweis. Ebenso kann ich sicher sein, dass mein Programm korrekt ist (z. B. nach umfangreichen Tests, Debugging und längerer Verwendung in der realen Welt, ohne dass Fehler auftreten), ohne es ein für alle Mal zu beweisen. Diese Interpretation kommt dem, was die meisten Leute meinen, wenn sie sagen "sicher, dass es richtig ist", viel näher. Formale Methoden sind ein Nischenproblem und für die meisten Entwickler völlig unberücksichtigt.

1
Ich sehe keine solche Frage. Die Frage, wie ich es lese, ist, warum die Notluke aus der verwalteten Welt nicht öfter verwendet wird / werden sollte (was bedeutet, dass die Standardeinstellung für verwalteten Code sinnvoll ist). Wenn Sie diese Frage beantworten möchten (indem Sie auf die Härte der Gewährleistung der Richtigkeit hinweisen), können Sie dies auf jeden Fall tun, ohne über die absolute, formale Gewährleistung der Richtigkeit zu sprechen . Ihre Antwort dreht sich ab sofort ausschließlich um vollständige, fundierte Korrektheitsnachweise für imperative Sprachen. Aber das ist übertrieben, und ich denke, Beweise für verwaltetes C # sind ebenso (oder fast genauso) schwierig.

1
@fish: Ich kann sehen, was du sagst. Es gibt eine Korrelation zwischen etwas, das schwer zu beweisen ist, und etwas, über das man nur schwer nachdenken kann. Wenn es schwierig ist, sich als richtig zu erweisen, ist es sehr wahrscheinlich schwierig, ziemlich sicher zu sein, dass es richtig ist.
Michael Shaw

0

Kurz gesagt, nichts hindert Sie daran, all diese Arbeiten auszuführen und Teile Ihres Programms in einer C ++ - Umgebung zu verwalten. Da Sie ziemlich sicher sind, dass Sie alle Speicherbereiche und Lecks ohne Garbage Collector korrekt verwalten können, können Sie dies gerne in C ++ tun :)

Im Gegensatz dazu bietet C # Vorteile bei der Bereitstellung einer sicheren / verwalteten und stark typisierten Entwicklungsumgebung für die sichere Ausführung in .NET Framework.

Der mögliche Nachteil beim Programmieren von nicht verwaltetem Code ist die längere Entwicklungszeit und die Zuweisung von Zeit für detaillierte Tests. Sie erhalten natürlich Verarbeitungsgeschwindigkeit und mehr Kontrolle darüber, wie Ihre Software ausgeführt wird.

Daher ist die Option, mit nicht verwaltetem Code in .NET Framework ab 4.0 zu arbeiten, eine Option für Randfälle, wenn Sie sicher sind, dass Sie dadurch Vorteile erzielen, wenn Sie ihn nicht verwenden ...


Aha, das ist interessant, du siehst, ich komme aus der Welt der Mikrocontroller und dort schreibt man normalerweise anständiges C ++. Es gibt wenig Raum für Fehler und ein gutes Design der Software ist der Schlüssel
user613326
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.