Moin,
angeregt durch das parallel laufende 737-MAX-Thema habe ich ein bisschen
über sicherheitskritische Programmierung gelesen. Die beiden großen
Kandidaten für sowas sind wohl Ada und MISRA-C(++). Aber wie sieht das
da mit der aktuellen Verteilung und der zukünftigen Entwicklung aus?
Ist Ada die Sprache, die man für sowas verwendet und MISRA-C ist nur der
Versuch, C-Programmierer in solchen Bereichen einsetzen zu können?
Oder ist Ada verbreitet, weil es früher benutzt wurde und
sicherheitskritische Systeme jahrzehntelang nicht wieder angefasst
werden, aber für Neuentwicklungen wird MISRA-C verwendet?
Darauf wird es wahrscheinlich keine klare Antwort geben, aber wie sind
die Erfahrungen derer, die sich mit sowas beschäftigt haben?
Mit zugedrütem Hühnerauge könnte man sagen dass wenn man die MISRA-C
Regeln in einen Compilerfrontend packt und dann die Syntax so ändert
dass eine nicht unerhebliche Menge an Fehler bereits beim hinschreiben
von Code verhindert wird, bei diese wie Ada ankommt.
Programmiersprachentheaterintendant schrieb:> Mit zugedrütem Hühnerauge könnte man sagen dass wenn man die MISRA-C> Regeln in einen Compilerfrontend packt und dann die Syntax so ändert> dass eine nicht unerhebliche Menge an Fehler bereits beim hinschreiben> von Code verhindert wird, bei diese wie Ada ankommt.
Warum gelingt es dir nicht, einen Gedanken klar zu formulieren und in
einen Text umzusetzen?
Bei Ada hat man halt einen großen Overhead was die Laufzeit betrifft …
meine Ada Erfahrung ist mini. Wenn dann wieder Klimmzüge gemacht
werden, weil Sicherheitszeiten in der Ausführung nicht mehr eingehalten
werden können -> doof! Die statische Codeanalyse für C/C++ ist ja
inzwischen auch recht weit.
Für "richtige" Ada Nutzung müssten wir unsere Architekten umerziehen
bezüglich erreichbarer Intervalle und Feature Set bei gegebener
Hardware.
MISRA Regeln können ja auch gebrochen werden. Das ist auch immer wieder
sinnvoll. Leider machen die On/Off Sequenzen für den Checker den Code
unleserlich.
MISRA ist vor allem für Einsteiger gut, denn es hatte ja schon jede
Regel ihren Ursprung. Da können sich insbesondere Anfänger bewusst
machen in was für "Fallen" man tappen kann und ihr Verständnis der
Programmiersprache vervollständigen.
Die meisten Fehler Programmiertechnisch treten bei uns im Zusammenhang
mit coolen generischen Sachen usw. auf. Die schleppen meistens
Absolventen und noch viel Schlimmer externe "Experten" an. Hier hat noch
nie einer der "Experten" wirklich etwas gebracht … vor allem wenn man
die Zeit zum einlernen auf dem konkreten System und die Übergaben mit
einrechnet. Das lernt so langsam zum Glück auch das Management -> aber
anderes Thema.
Ich würde auch die Programmiersprache heute nicht mehr in den
Vordergrund stellen wollen. Erfahrungsgemäß kommen die kritischen Fehler
meist eher durch mangelndes Systemverständnis zustande, oder wurden
direkt vom Architekten schön ins System geplant. Man sollte natürlich
auch darauf achten, dass man nicht rückläufig in der Qualität wird was
den Code betrifft.
Hier in der Firma haben die Safety Projekte den fast 10x Codeumfang wie
noch vor 10 Jahren! Dennoch sind die Zahlen für echte Programmier-Fehler
auch absolut rückläufig. Dafür sind stark ansteigende Fallzahlen von
Konzeptfehlern heute ein Problem. Die bekommt man aber weder mit MISRA
als auch Ada in den Griff. Hier scheitert dann oft auch das Unittesting
und bei dem großen Funktionsumfang ist eine echte 100% Abdeckung im
Systemtest sowas von Utopie!
Sprich das Testen über Simulationen wird immer wichtiger!!! Wenn man das
Feature Set von vor 10 Jahren auf dem äquivalenten Anteil von heute
abbildet, dann sind sogar dort die Fehlerzahlen rückläufig. Allerdings
steigen die Problemeund Fehler insgesamt durch die großen
Querbeeinflussungen durch die hohe Anzahl an Funktionen, welche man
untergebracht hat.
Übrigens Ada wird heute immer noch in gewissem Umfang bei deutschen
Banken eingesetzt. Vielleicht wechselt die Commerzbank ja gerade auf
Java :D
Addada schrieb:> Wird Ada eigentlich überhaupt in Deutschland komerziell eingesetzt
Natürlich
Softwareentwickler (m/w/d) ADA / JAVA Bahntechnik
ALTEN GmbH - Stuttgart 20.06.2019 mehr...
Softwarentwickler/-in ADA (w/m)
Airbus Group SE - Ulm 06.06.2019 mehr...
Hardwarenaher Softwareentwickler (m/w/d) mit Ada-Kenntnissen
(Softwareentwickler/in)
Computer Futures - München, Deutschland, Bayern, Ingolstadt 12.03.2019
Dussel schrieb:> Ist Ada die Sprache, die man für sowas verwendet und MISRA-C ist nur der> Versuch, C-Programmierer in solchen Bereichen einsetzen zu können?> Oder ist Ada verbreitet, weil es früher benutzt wurde und> sicherheitskritische Systeme jahrzehntelang nicht wieder angefasst> werden, aber für Neuentwicklungen wird MISRA-C verwendet?>
Ich würde nach wie vor auf Ada setzen, da es doch etwas mehr an
protektivem Framework mitbringt als C. Dazu ist meiner Meinung nach
MISRA eine ziemliche Augenwischerei, bis teilweise fragwürdig und nicht
wirklich bis zum Ende durchdacht. Gibt hier ne detailliertere Analyse:
http://www.knosof.co.uk/misracom.html
Man kann auf jeden Fall nach MISRA Code schreiben, der unter
hochgelobten MISRA-Compilern keine Warnungen wirft, aber in der
Simulation durchfällt. GCC ist da u.U. mit seiner Analyze 'wörtlicher'.
Bin mir da nicht sicher, ob MISRA einem 'Absolventen' wirklich hilft...
> Darauf wird es wahrscheinlich keine klare Antwort geben, aber wie sind> die Erfahrungen derer, die sich mit sowas beschäftigt haben?
Auf jeden Fall sollte man sich nicht in Sicherheit wiegen und zumindest
Coverage und eine saubere Simulation machen oder zumindest wissen, wie
der C-Compiler bzw. die CPU-Architektur arbeitet. Gewisse System-Sachen
gehen in Ada auch nicht so einfach von der Hand.
Ist halt immer die Frage, wie gross der Aufwand sein darf, und welche
Safety erforderlich ist, für eine wenig-Mann/Frau-Bude ist primär eine
Frage der Haftung.
Yammi schrieb:> Die meisten Fehler Programmiertechnisch treten bei uns im Zusammenhang> mit coolen generischen Sachen usw. auf. Die schleppen meistens> Absolventen und noch viel Schlimmer externe "Experten" an. Hier hat noch> nie einer der "Experten" wirklich etwas gebracht … vor allem wenn man> die Zeit zum einlernen auf dem konkreten System und die Übergaben mit> einrechnet. Das lernt so langsam zum Glück auch das Management -> aber> anderes Thema.
Die allergrößten Probleme entstehen dann, wenn mehrere unabhängig
voneinander entwickelten Produkte im Zuge strategischer Zusammenarbeit
oder Unternehmensübernahmen dann zwangsweise zusammengeführt werden
müssen. Schließlich hat ja der M&A-Synergieberater erhebliche
Kosteneinsparungen und Effizienzgewinne versprochen. Solche Produkte
sind dann häufig völlig inkonsistent bzw. Teilfunktionen weisen komplett
andere Entwicklungs- und Bedienphilosophien auf. Und die jeweiligen
Entwicklermannschaften liefern sich dann interne Kleinkriege bis zur
Rente oder internen Kündigung, sofern sie nicht vorzeitig gehen.
Das "Meisterstück" an solch einer verpfuschten Software ist "Oracle
Collaboration Suite". Dem Kunden wurde die eierlegende Wollmilchsau für
die unternehmensinterne Kommunikation versprochen. Oracle hatte einfach
eine Handvoll Start-Ups und etablierte Unternehmen aufgekauft und deren
Software in eine Tüte gestopft. Bekannte von mir arbeiteten in einem
Systemhaus, das ein paar Jahre lang versucht hatte, die "Collaps Suite"
sowohl intern als auch bei Kunden zum Laufen zu bringen, was aber nicht
gelang. Oracle selbst hat das Produkt dann auch wie eine heiße Kartoffel
fallen lassen.
Auf der rein technischen Ebene habe ich aber auch schon ähnlichen Mist
erlebt: ein Kunde hat sich von einem Vertriebler ein Entwicklungsboard
aufschwatzen lassen, auf dem ein mit äußerst heißer Nadel gestricktes
Embedded Linux lief, d.h. man konnte auf der UART-Schnittstelle
zuschauen, wie ein Kernel bootete. Laut Vertriebler müsse man "nur noch"
eine Applikation schreiben und alles sei fertig. Im Serienprodukt sollte
zudem ein exotischer Flash-Baustein zum Einsatz kommen, für den es sogar
ein paar Bare-Metal-Treiberquellen gab. Der Hardwareentwickler,
gleichzeitig Projektleiter, meinte, man müsse diesen Treiber ja einfach
nur noch kompilieren und sei dann fast fertig mit den gesamten
Anpassungen; er sah also nur wenige Tage Aufwand. Ich veranschlagte nur
für die ersten Anpassungen an die Hardware jedoch drei Mannmonate, die
auch der Entwicklungsleiter für realistisch hielt. Da aber noch viel,
viel mehr zu erledigen war (Infrastruktur, Schulung, Buildsystem,
Hardwareintegration, Fertitungstest, Dokumentation, Zertifizierung),
arbeiteten einer meiner Mitarbeiter und ich insgesamt fünfeinhalb
MannJAHRE daran.
Dussel schrieb:> Die beiden großen> Kandidaten für sowas sind wohl Ada und MISRA-C(++).
Wobei ich MISRA-C noch um Lint und weitere Analysetools erweitern würde.
C ist einfach die am Besten erforschte Programmiersprache, so dass es
dazu das größte Biotop gibt.
Ich meine, mal gelesen zu haben, dass die NASA auf die Frage, welche
statische Analysetools, die Antwort fand: Alle (bzw. alle relevanten).
Warum auf Lint beschränken, wenn andere Tools andere Fehler finden.
Uns hilft PC-Lint sehr, da es relativ flexibel an alle
Programmierparadigmen angepasst werden kann und z.B. MISRA-Richtlinie am
umfangreichsten prüft.
Da sind ja doch schon einige gute Antworten zusammengekommen.
Der Hintergrund der Frage war, dass ich überlege, in die Richtung mehr
zu lernen. Schwere Schäden durch Softwarefehler gab es immer wieder. Da
war halt die Frage, ob es sich lohnt, sich auf Ada zu konzentrieren oder
ob das in nächster Zeit durch andere Techniken (MISRA, Codeanalyse)
ersetzt wird.
In dem Fall wäre es wahrscheinlich besser, sicheres C und den Umgang mit
Analysewerkzeugen zu lernen.
Simulation und ausführliche Tests kann man sowieso nicht ersetzen. Aber
man kann eventuell durch die richtige Herangehensweise Fehler vermeiden
und die Fehlersuche verkürzen. Und mit mühsamer Fehlersuche in C(++)
habe ich doch schon unschöne Erfahrung gemacht.
Welche Entwicklung? Der Status Quo ist die aktuelle Entwicklung. C ist
im Embedded Bereich verbreiteter denn je und Alternativen interessieren
in Wahrheit niemanden. Gewünscht wird billiger Massencode der an Leute
in Fernost nach 2-Monaten Programmier-Crashkurs ge-out-sourced werden
kann.
Die Welt "da draußen" schaut in Wahrheit nicht viel anders aus als das
Projekte & Code Unterforum. Massenweise C-Code mit raw-pointer,
impliziten Typumwandlungen und keinem einzigen Unit-Test.
Dussel schrieb:> Da sind ja doch schon einige gute Antworten zusammengekommen.> Der Hintergrund der Frage war, dass ich überlege, in die Richtung mehr> zu lernen. Schwere Schäden durch Softwarefehler gab es immer wieder.
Was Dir vielleicht noch nicht so klar ist:
Sichere Software ist zum einen natürlich der Wunsch, wenig Fehler zu
machen und qualitativ hochwertige Software zu schreiben.
Zum anderen ist es aber auch in vielen Branchen einfach Vorschrift. Da
gibt es Normen (z.B. ISO26262 in der Automobilbranche), in denen steht
wie man sichere Software zu entwickeln hat.
Sichere Softwareentwicklung ist aber ziemlich teuer. Deswegen will das
niemand. Man macht das nur, wenn es unbedingt nötig ist (z.B. weil es um
Menschenleben geht) und selbst dann schaut man sehr genau hin, wie
sicher es denn nun werden muss.
> Da> war halt die Frage, ob es sich lohnt, sich auf Ada zu konzentrieren oder> ob das in nächster Zeit durch andere Techniken (MISRA, Codeanalyse)> ersetzt wird.> In dem Fall wäre es wahrscheinlich besser, sicheres C und den Umgang mit> Analysewerkzeugen zu lernen.
Das könnte auch von der Branche abhängen. Ich kenne Misra C aus der
Automobilbranche, aber weiter oben wurden ja ein paar Stellenanzeigen
für Ada genannt und da ging es um Bahntechnik und Flugzeuge.
Markus K. schrieb:> Sichere Softwareentwicklung ist aber ziemlich teuer. Deswegen will das> niemand. Man macht das nur, wenn es unbedingt nötig ist (z.B. weil es um> Menschenleben geht) und selbst dann schaut man sehr genau hin, wie> sicher es denn nun werden muss.
Es muss ja nicht immens teuer sein. Man kann auch um die teuren Tools
einen Bogen machen.
Teurer wird's, wenn die Bude in die Haftung genommen wird, wenn Mist
passiert. Das Szenario durchzuspielen scheint nur sehr unpopulär und
viele Frickelbuden meiden das Thema nach Schema "shoot the messenger",
sprich, wer die Fehler aufdeckt, ist erst mal ein Störer.
Dabei ist es eine ganz einfache Risikorechnung, die auch bei der Regel
"billig vor gründlich" recht eindeutig rauskommt. Das Debuggen kostet
fast immer mehr als das Entwickeln. Wenn man da rechtzeitig die Weichen
stellt, ist das unterm Strich nicht teurer.
Dussel schrieb:> In dem Fall wäre es wahrscheinlich besser, sicheres C und den Umgang mit> Analysewerkzeugen zu lernen.
Für Server-Anwendungen machste Dir damit schon sicher Freunde, vor allem
wenn malloc()/free() (new/delete) mit im Spiel ist. Für embedded auch.
Aber grundsätzlich kann man sich auch überlegen, Dinge in HW zu
verfrachten, oder sich bei guten alten Konzepten aus der Raumfahrt
bedienen .
Interessant wäre, was die Rust-Community zu dem Thema sagt. Ich hoffe
auf den nächsten Paradigmenwechsel. Denn die statische Code-Analyse
bleibt leider immer ein Klimmzug und MISRA mehr oder weniger eine Farce.
Markus K. schrieb:> Sichere Softwareentwicklung ist aber ziemlich teuer. Deswegen will das> niemand.
In dem Bereich, an den ich bei dem Thema vorzugsweise denke, geht es um
ein paar Millionen Euro…
Markus K. schrieb:> Ich kenne Misra C aus der> Automobilbranche, aber weiter oben wurden ja ein paar Stellenanzeigen> für Ada genannt und da ging es um Bahntechnik und Flugzeuge.
Also scheint beides verbreitet zu sein und wie VHDL und Verilog je nach
Branche oder Land bevorzugt zu werden.
Martin S. schrieb:> sich bei guten alten Konzepten aus der Raumfahrt bedienen
An die denke ich. :-) Wobei bei der Raumfahrt wahrscheinlich noch andere
Anforderungen dazukommen.
Dann werde ich mal sehen. Sich in Konzepte zum sicheren Programmieren
einzuarbeiten ist sicher nicht verkehrt. Bei Gelegenheit kommt dann noch
Ada dazu.
Dussel schrieb:> Markus K. schrieb:>> Sichere Softwareentwicklung ist aber ziemlich teuer. Deswegen will das>> niemand.> In dem Bereich, an den ich bei dem Thema vorzugsweise denke, geht es um> ein paar Millionen Euro…
Das ist sicher auch ein Grund, um mehr Wert auf Qualität zu legen.
Wobei ein paar Millionen Euro für die meisten größeren Firmen nicht so
übermäßig viel Geld ist.
> Markus K. schrieb:>> Ich kenne Misra C aus der>> Automobilbranche, aber weiter oben wurden ja ein paar Stellenanzeigen>> für Ada genannt und da ging es um Bahntechnik und Flugzeuge.> Also scheint beides verbreitet zu sein und wie VHDL und Verilog je nach> Branche oder Land bevorzugt zu werden.
Ja, wobei es wohl gerade in Deutschland wohl mehr Autohersteller als
Flugzeugbauer gibt.
Es gibt auch noch andere Sprachen, z.B. die SPS-Sprachen (Structured
Text usw.). Wenn Du z.B. eine fertige programmierbare Steuerung kaufst
mit der Du sicherheitskritische Sachen schalten willst, dann gibts dort
oftmals nur die bei den SPS üblichen Programmiersprachen.
> Martin S. schrieb:>> sich bei guten alten Konzepten aus der Raumfahrt bedienen> An die denke ich. :-) Wobei bei der Raumfahrt wahrscheinlich noch andere> Anforderungen dazukommen.>> Dann werde ich mal sehen. Sich in Konzepte zum sicheren Programmieren> einzuarbeiten ist sicher nicht verkehrt. Bei Gelegenheit kommt dann noch> Ada dazu.
Das Programmieren (also das Code schreiben) ist dabei aber nur ein
kleiner Teil. Es fängt vorne an (Anforderungen systematisch
aufschreiben) und hinterher systematisch auf allen Ebenen testen. Und
natürlich besteht ein Gerät ja nicht nur aus Software, d.h. auch der
Rest (Elektronik/Mechanik) muss entsprechend entwickelt werden. Da macht
man dann so was-wäre-wenn-Überlegungen: Wenn dieser Widerstand von der
Platine abfällt/einen Kurzschluss bekommt, was passiert dann? Wie kann
man das erkennen?
Das ganze Thema Funktionale Sicherheit kann sehr spannend sein, aber
auch sehr mühsam, denn es kann z.B. bedeuten, dass für deine Unit-Tests
decision coverage verlangt wird.
https://en.wikipedia.org/wiki/Modified_condition/decision_coverage
sparky schrieb:> A. S. schrieb:>> Dussel schrieb:>>> Die beiden großen>>> Kandidaten für sowas sind wohl Ada und MISRA-C(++).>>>> Wobei ich MISRA-C noch um Lint und weitere Analysetools erweitern würde.>> Dann sollt man auch Ada-SPARK vergessen:>> https://www.golem.de/news/ada-und-spark-mehr-sicherheit-durch-bessere-programmiersprachen-1906-141211.html
Denke, du meintest wohl „nicht vergessen“. :)
ADA mit SPARK gibt nicht nur sicheren Code, sondern auch verifizierten
Code. In manchen Branchen eine conditio sine qua non. Leute, die das
können, sind gefragt und gut bezahlt.
Gruß
Herby
Markus K. schrieb:> Wobei ein paar Millionen Euro für die meisten größeren Firmen nicht so> übermäßig viel Geld ist.
Das war ein bisschen vorschnell. Curiosity hat laut Wikipedia wohl ein
paar (über zwei) Milliarden Dollar gekostet.
Bei der NASA werde ich wohl auch in Zukunft nicht arbeiten, aber
vielleicht in Bereichen, in denen die Schäden sehr hoch werden könnten.
Außerdem gibt es ja auch andere Bereiche für sichere Programmierung.
Markus K. schrieb:> Das Programmieren (also das Code schreiben) ist dabei aber nur ein> kleiner Teil. Es fängt vorne an (Anforderungen systematisch> aufschreiben) und hinterher systematisch auf allen Ebenen testen.
Ich weiß. Das wurde ja oben schon geschrieben. Aber sowas macht man ja
nicht alleine. Softwareentwickler sind für die Sicherheit der Software
zuständig und müssen sich wohl eher weniger um die Hardware kümmern und
umgekehrt.
Hier ging es mir nur um die Programmierung.
Dussel schrieb:> Softwareentwickler sind für die Sicherheit der Software> zuständig und müssen sich wohl eher weniger um die Hardware kümmern und> umgekehrt.
Ein ordentlicher Teil der Hardwareprobleme wird aber in Software
erkannt.
Beispiel: Das Gerät darf nicht überhitzen. Also bekommt das Gerät einen
Temperatursensor. Aber der könnte ja defekt sein. Also zwei Sensoren,
einen NTC, der per A/D-Wandler eingelesen wird, und einen digitalen
Sensor, der per I²C gelesen wird. Wenn die Temperatur zu hoch wird oder
sich die Sensoren nennenswert widersprechen, dann soll sich das Gerät
ausschalten.
Auch kann natürlich der Flashspeicher/das RAM/die CPU kaputtgehen und
auch das muss dann erkannt werden.
Oder die Kamera verschmutzt, ...
Das ist dann Deine Aufgabe als Softwareentwickler. Es ist nicht das, was
Du unter sicherer Software verstehst, aber dieser Teil der Software ist
essentiell für ein sicheres Gerät.
Ada wird durchaus eingesetzt, allerdings nahezu ausschließlich in der
Luft- und Raumfahrt. In anderen Branchen scheint es sehr wenig vertreten
zu sein.
Mark B. schrieb:> Ada wird durchaus eingesetzt, allerdings nahezu ausschließlich in der> Luft- und Raumfahrt. In anderen Branchen scheint es sehr wenig vertreten> zu sein.
Vielleicht wirklich aus Kostengründen. In Luft- und Raumfahrt ist man
bereit, die spezialisierten Ada-Programmierer zu bezahlen, während die
anderen Bereiche eher kostenkritischer sind und man C-Programmierer
nimmt und die durch MISRA und andere Werkzeuge sicher macht. (Nichts
gegen C-Programmierer, ich bin ja selber einer.)
Ich würde noch Rust als Alternative zu Misra-C oder Ada ins Spiel
bringen. Obwohl es (leider) nicht primär für Embedded-Applikationen
gedacht war, tut sich in diesem Bereich schon jetzt sehr viel, so gibt
es etwa schon einen - nicht perfekten aber sehr brauchbaren -
Stackanalyzer:
https://blog.japaric.io/stack-analysis/
Was dem Rust-Ökosystem gerade im Embeddedumfeld fehlt sind Firmen die
professionellen Support bieten. Gerade da sehe ich aber eine Chance auch
für Freelancer oder kleinere Firmen.
Meiner Meinung nach vereint Rust die Vorteile von C, C++ und Ada auf
geradezu einzigartige Art und Weise. Es ist so performant wie C, hat
jedoch eine starke Typisierung wie C++ und bietet eine erhöhte
Sicherheit, dass der Code auch das macht was er soll wie etwa Ada. Vom
Verbreitungsgrad ist es zwar momentan noch weit hinter C und C++, jedoch
sicher weit vor Ada, wobei sich das über die nächsten Jahre sehr zu
Gunsten von Rust ändern könnte, da immer mehr low-level Applikationen in
der "nicht-embedded" Welt in Rust geschrieben werden, statt in C oder
C++.
Das Problem mit neuen Sprachen besteht darin, dass viele Codegeneratoren
und Bibliotheken auf C/C++ ausgerichtet sind. Insbesondere im
Microcontrollerbereich gibt es Werkzeuge wie STM Cube MX, die eben
Konfigurationsdateien und Treibergerüste in C erzeugen. Arbeitet man mit
Vivado an einem FPGA-Projekt, aus welchem heraus ein Softwareprojekt
erstellt wird, wird natürlich C-Code erzeugt, usw.. Diese beiden
Programme habe ich nur exemplarisch gewählt, denn es gibt natürlich noch
wesentlich mehr derartige Fälle.
Mir wäre hingegen kein vergleichbares freies oder kommerzielles Werkzeug
bekannt, welches Low-Level-Rust-Code generiert.
Gibt es denn bei Rust wirklich ressourcenschonende und praktikble Wege,
ein gemischtes Projekt zu erzeugen? Und wie sieht es mit der
Compilerunterstützung aus?
Andreas S. schrieb:> Mir wäre hingegen kein vergleichbares freies vcvxvvvvvvvvv Werkzeug> bekannt, welches Low-Level-Rust-Code generiert.
Es gibt SVD2Rust, was aus den SVD-Dateien Low-Level-Rust-Code erzeugen.
Es ist jedoch "nur" das Äquivalent zu den CMSIS-Headern, d.h. man
bekommt Structs für die komplette Peripherie. So etwas wie CubeMX gibt
es momentan aber noch nicht.
Andreas S. schrieb:> Gibt es denn bei Rust wirklich ressourcenschonende und praktikble Wege,> ein gemischtes Projekt zu erzeugen? Und wie sieht es mit der> Compilerunterstützung aus?
Gemischte Projekte sind kein Problem. Compilermäßig sind GCC und
Clang/LLVM voll unterstützt. Standardmäßig nutzt Rust den LLD, also den
LLVM-Linker, wobei der GCC-Linker ebenso unterstützt wird und
ursprünglich für Cortex-M sogar der Standardlinker war. Wie es mit der
Kompatibilität mit Keil oder IAR aussieht kann ich nicht genau sagen
aber da Keil neuerdings ebenfalls auf Clang/LLVM beruht könnte das auch
funktionieren.
Ein Beispiel für die Kombination von C und C++ mit Rust ist der Tock
Kernel. Tock ist ein komplett in Rust geschriebenes RTOS, wobei man für
die eigentliche Applikation die freihe Wahl zwischen Rust, C und C++
hat. Es gibt dann entsprechend eine libtockrs, libtockc oder libtockcxx.
Für Beispiele siehe etwa
https://github.com/tock/libtock-c/blob/master/examples/sensors/main.c
oder
https://github.com/tock/libtock-c/blob/master/examples/cxx_hello/main.cc
Ob es sinnvoll ist einen OS-Kernel in Rust und die eigentliche Anwendung
in C zu schreiben sei jetzt mal dahingestellt. Ich persönlich würde es
wohl eher andersherum machen. Rust ist aber grundsätzlich sehr
kompatibel zu C.
Christopher J. schrieb:> Ich würde noch Rust als Alternative zu Misra-C oder Ada ins Spiel> bringen. Obwohl es (leider) nicht primär für Embedded-Applikationen> gedacht war, tut sich in diesem Bereich schon jetzt sehr viel, so gibt> es etwa schon einen - nicht perfekten aber sehr brauchbaren -> Stackanalyzer:
Wie sieht es mit valgrind aus, kann man das (mit Debug-Symbolen) schon
sinnvoll verwenden? Und wie gehn coverage-Tests (gcov?) von der Hand?
Christopher J. schrieb:> Ob es sinnvoll ist einen OS-Kernel in Rust und die eigentliche Anwendung> in C zu schreiben sei jetzt mal dahingestellt. Ich persönlich würde es> wohl eher andersherum machen. Rust ist aber grundsätzlich sehr> kompatibel zu C.
Das ist ein interessanter Punkt, der auch gelegentlich bei der Frage C
vs. C++ aufflackert. Beispiel: Ich habe hier ein Kernel, was ohne
malloc() arbeiten muss, aber eine gewisse (begrenzte) Anzahl von vielen
Objekten alloziert und immer wieder freigibt, d.h. es läuft intern auf
verlinkte Listen raus.
In C ist das nervige Schreibarbeit mit Iteratoren-Makros, in C++ wär's
schöner, aber gibt ein paar Showstopper für diese Architektur (u.A.
stack unwinding/Exceptions). Habe schon gesehen, dass man in Rust
relativ elegant Allokatoren definieren kann. Wie sieht das in der Praxis
aus, macht das engineering-mässig Sinn, ein Mikro-Kernel in C zu
schreiben und einen Applikations-Layer in Rust drüberzukleben? D.h. wie
einfach ist es, ein Objekt mit einem Listen-Kopf (C-Struct mit .next,
.prev, .children und einer Objekt-Nutzlast) zu wrappen? Und: es darf
keine Template-Orgie a la C++ werden, da Mikrocontroller...
> Das Problem mit neuen Sprachen besteht darin, dass viele Codegeneratoren> und Bibliotheken auf C/C++ ausgerichtet sind.
Ach, da koennen einem noch weitere Probleme einfallen. Zum Beispiel
Compiler die bestimmte Zertifizierungen aufweisen. (SIL) Oder auch
schlicht die Tatsache das jeder der im Embedded Bereich antritt perfekte
C Kenntnisse haben muss weil ja der Source der letzten 20Jahre in C
geschrieben wurde und den muss er immer noch warten, gelegentlich von
Fehler befreien oder erweitern und in neuen Anwendungen weiter verwenden
koennen. Wenn er also schon mal diese Kenntnisse aufweisst, warum sollte
er sich dann noch eine zusaetliche Sprache antun? Und zwar fuer
mindestens 10Jahre, in der Industrie gelten andere Zyklen als bei
Endkundenware.
Das Problem mit C ist halt einfach das die Sprache da ist. Es weiss auch
jeder das Microsoft oder Word schlecht ist, aber auch das ersetzt man
nicht mal eben so.
Ausserdem hat C den grossen Vorteil einfach zu funktionieren, mit der
Betonung auf "einfach". Bei vielen neuen Modesprachen hab ich den
Eindruck als wenn sich da irgendwelche jugendlichen Informatikjuenger
vor allem einen drauf abrubbeln wollen und es weniger auf
Funktionalitaet ankommt.
Olaf
Strubi schrieb:> Wie sieht das in der Praxis aus, macht das engineering-mässig Sinn, ein> Mikro-Kernel in C zu schreiben und einen Applikations-Layer in Rust> drüberzukleben
Warum nicht den Kernel auch in Rust?
Strubi schrieb:> Und: es darf keine Template-Orgie a la C++ werden, da> Mikrocontroller...
Wieso? Ob man den Boilerplate-Code fehleranfällig und unwartbar von Hand
schreibt oder automatisch per Templates generieren lässt, das Ergebnis
in Form von Maschinencode sieht gleich aus. Templates haben an sich
keinerlei Overhead! Templates sind gerade für Mikrocontroller gut, wo
man teure Laufzeit-flexibilität durch Compiletime-Konfigurierbarkeit
abwägen muss.
Olaf schrieb:> Ausserdem hat C den grossen Vorteil einfach zu funktionieren, mit der> Betonung auf "einfach". Bei vielen neuen Modesprachen hab ich den> Eindruck als wenn sich da irgendwelche jugendlichen Informatikjuenger> vor allem einen drauf abrubbeln wollen
Und hier ist es wieder, das Informatiker Bashing. Wie macht man denn
z.B. in C "einfach" String-Verarbeitung, so einfach wie in der
Modesprache Java? Oder typsichere Container (Gut für verlässliche
Software!)? Oder strikte Kapselung? Hast du mal in einer der sogenannten
Modesprachen gearbeitet und festgestellt wie schön es ist sich von den
Restriktionen des uralten C lösen zu können und nicht zum 1000. Mal
darüber nachzudenken wie man Strings konkateniert?
Von wegen "abrubbeln" - wer mit Leidenschaft dabei ist und gute Produkte
abliefern möchte, freut sich über gute, wartbar, zuverlässige robuste
Lösungen. Wie sie moderne Sprachen ermöglichen. Nicht jeder ist ein
Konzernbeamter der mit seinen Kenntnissen von 1990 sein gesamtes
Berufsleben bestreitet und mit Neuerungen bloß in Ruhe gelassen werden
möchte.
> Nicht jeder ist ein Konzernbeamter der mit seinen Kenntnissen von 1990> sein gesamtes Berufsleben bestreitet und mit Neuerungen bloß in Ruhe> gelassen werden möchte.
Hihi, da bin ich ganz bei dir. :) Aber alle gesammelten Erkenntnisse
seit 1990 werden immer noch verwendet und verkauft. Die kann man nicht
ignorieren und einfach sagen wir machen etwas neu. Ich sehe die
Nachteile von C durchaus. Aber der darin geschriebene Code muss weiter
verwendbar bleiben. Du kannst nicht 20Jahre Entwicklung einfach in
2Monaten neu schreiben.
Olaf
Olaf schrieb:> Aber der darin geschriebene Code muss weiter> verwendbar bleiben. Du kannst nicht 20Jahre Entwicklung einfach in> 2Monaten neu schreiben.Dagegen sagt ja auch keiner was. Aber es werden auch neue Projekte
gestartet, und dafür kann man neue Technologien verwenden. Und nicht
alles, was nach C erfunden wurde, ist eine Modeerscheinung. Tatsächlich
ist eher C die Mode, weil so viel da irrational dran fest klammern!
Dr. Sommer schrieb:> Wieso? Ob man den Boilerplate-Code fehleranfällig und unwartbar von Hand> schreibt oder automatisch per Templates generieren lässt, das Ergebnis> in Form von Maschinencode sieht gleich aus. Templates haben an sich> keinerlei Overhead! Templates sind gerade für Mikrocontroller gut, wo> man teure Laufzeit-flexibilität durch Compiletime-Konfigurierbarkeit> abwägen muss.
Man kann Templates schon so schreiben, dass sie wenig Overhead
generieren. Aber immer noch Overhead, gegenüber der handgestrickten
Lösung. Alles schon durchgespielt.
C++ hat in einem robusten Kernel generell nichts zu suchen, den Fehler
haben schon einige im näheren Umkreis gemacht. Hier gilt die Regel:
schreibe expliziten Code nach einem vorgegebenen Schema. Das ist weder
fehleranfällig noch unwartbar und schreit somit auch nicht nach
Verbesserung. Je expliziter Code generiert wird, desto verifizierbarer
ist er auch (Coverage-Tests).
C++ ist im 'Userspace' (auch auf dem uC) legitim und wird da auch
gebraucht, man kann sich nur kräftig ins Knie schiessen. Wenn Rust
gewisse Fehler/Sprachmissbrauch einfach nicht mehr erlaubt (dazu gehört
auch das problematische Exception-Handling), wäre es ein besserer
Kandidat als C++.
Ich bin generell der Meinung: Wenn eine Vielzahl von
Programmier-Regeln/Guidelines einer klassischen Sprache einer Sprache
gegenübersteht, die gewissen Unfug schon einfach nicht erlaubt, lerne
ich lieber die neue Sprache, sofern das Framework nicht 'broken by
design' ist. Der Rest sind Engineering-Details (API,
Calling-Conventions) die einfach stimmen müssen. Bei C++ ist leider
einiges broken by design, aber ich möchte diese Diskussion hier nicht
(zum x-ten mal) führen..
Strubi schrieb:> Man kann Templates schon so schreiben, dass sie wenig Overhead> generieren. Aber immer noch Overhead, gegenüber der handgestrickten> Lösung.
Interessant, hast du ein Beispiel? Das kann eigentlich nur sein, wenn
die handgestrickte Lösung irgendwelche fall-spezifischen Optimierungen
hat.
Strubi schrieb:> C++ hat in einem robusten Kernel generell nichts zu suchen, den Fehler> haben schon einige im näheren Umkreis gemacht.
Ich habe in C++ schon erfolgreich Kernel geschrieben und mich gefreut,
wie schön man die Datenstrukturen in Klassen packen kann.
Strubi schrieb:> Bei C++ ist leider> einiges broken by design,
Ja, die Sachen die aus C übernommen wurden...
> Dagegen sagt ja auch keiner was. Aber es werden auch neue Projekte> gestartet, und dafür kann man neue Technologien verwenden.
Natuerlich kommt das vor. Aber auch da hast du gerne mal 20-50%
Weiterverwendung von altem Code. Und selbst wenn nicht, du hast dann
immer noch 3-5 Ingenieure in deinem Team die 1990 angefangen haben und
deine neue Modesprache nicht koennen. Aber die sind auch unverzichtbar
weil sie die Erfahrung mitbringen die fuer ein Embedded-Projekt
notwendig ist.
Und die lernst du auch nicht um weil Informatik-Gebabbel heute genauso
verstaendlich ist wie eine Steuererklaerung. Was ich den Informatikern
vorwerfe das sie in ihren Elfenbeintuermen bei Chips und Pizza hausen
und sich eine neue coole Sprache nach der anderen ausdenken, aber dabei
vergessen das draussen in der Welt damit normale Leute normale
Anwendungen schreiben sollen. Leute mit Etechnik oder
Maschinenbaustudium weil dieses Fachwissen der wichtige Teil der
Anwendung ist und nicht die Geheimnisse der esoterischen Informatik.
> Tatsächlich ist eher C die Mode, weil so viel da irrational dran fest> klammern!
Aehem..die Idee von Mode ist es eigentlich die Leuten zum kauf von neuen
Klamotten anzuregen wenn das alte noch gut genug ist. .-)
BTW: Ich warte immer noch darauf das Smalltalk alle anderen Sprachen
abloesst weil das jetzt die neue coole Sau im Dorf ist. Ich kann mich
noch gut erinnern wie mir das um 2000 jeder erzaehlt hat.
Olaf
Olaf schrieb:> Natuerlich kommt das vor. Aber auch da hast du gerne mal 20-50%> Weiterverwendung von altem Code.
Tja, unter den JVM-basierten Modesprachen kann man alten Code super
weiter verwenden, da binärkompatibel.
Olaf schrieb:> Und die lernst du auch nicht um weil Informatik-Gebabbel heute genauso> verstaendlich ist wie eine Steuererklaerung.
Im Gegenteil sind die Einführungen zu modernen Sprachen viel
zugänglicher als C. Jeder Anfänger fragt sich was dieses kryptische
"char* argv[]" heißen soll...
Olaf schrieb:> Was ich den Informatikern> vorwerfe das sie in ihren Elfenbeintuermen bei Chips und Pizza hausen> und sich eine neue coole Sprache nach der anderen ausdenken, aber dabei> vergessen das draussen in der Welt damit normale Leute normale> Anwendungen schreiben sollen
Liest du nur TheoInf-Publikationen? z.B. die Sprache Kotlin ist so
einfach, dass man sie "en passant" lernen kann. Mit Java-Kenntnissen
versteht man sofort was passiert, und dank des großartigen automatischen
Refactoring von z.B. Android Studio lernt man direkt wie man Kotlin
effektiv nutzt. So kann man seine Codebasis easy Stück für Stück
umstellen oder auch nur neue Module in Kotlin schreiben - ist ja alles
kompatibel!
Es gibt heutzutage schicke Online-Tutorials welche die aktuellen
Sprachen Stück für Stück erklären, sogar direkt mit Online-Kompilieren.
Das hat nichts mit Elfenbeinturm zu tun.
Sprachen wie Python lernen sogar Kinder, weil sie so eingängig sind.
Klar steckt im Parser eine Menge theoretische Informatik, aber das
interessiert den Nutzer der Sprache nicht. Rate mal warum Python eine
der bevorzugten Sprachen beim R-PI ist... Ok, Python ist nicht brandneu,
aber definitiv aktuell.
Rust macht so vom schnellen ersten Überblick einen guten Eindruck.
Aber beruflich gesehen bleibt die Frage, ob es sinnvoll ist, das zu
lernen. Wir wissen wahrscheinlich alle, dass die Industrie, gerade im
sicherheitskritischen Bereich, oft sehr träge ist (bei einer Firma wurde
vor Kurzem ein Prozessor von 1990 für neue Projekte ersetzt).
Da weiß man halt nicht, ob Rust eine Chance hat oder es aus praktischen
Gründen doch bei MISRA-C oder Ada bleibt.
Olaf schrieb:> Bei vielen neuen Modesprachen hab ich den> Eindruck als wenn sich da irgendwelche jugendlichen Informatikjuenger> vor allem einen drauf abrubbeln wollen und es weniger auf> Funktionalitaet ankommt.
Naja, dem kann ich nicht so ganz zustimmen.
Allerdings habe ich den Eindruck, dass sich sehr viele
Informatik-Professoren unsterblich machen wollten, indem sie irgendeine
Programmiersprache erfinden. Teilweise hat es da natürlich auch
interessante Ideen gegeben, aber das allermeiste hat glücklicherweise
den Dunstkreis des jeweiligen Lehrstuhls nicht verlassen.
Interessanterweise hat sogar das Internet die tolle Programmiersprache
FUNGOL von Prof. Jammel vergessen, d.h. man findet nur noch das
gleichnamige Holzschutzmittel.
Die erwähnten "Modesprachen", die tatsächlich über den Lehrstuhl hinaus
bekannt wurden, sind häufig durchaus gut verwendbar. Interessant ist
dabei aber auch, wie alt manche dieser Sprachen schon sind, sobald sie
für die Allgemeinheit wirklich sichtbar werden. Als Python zum heißen
Scheiß wurde, war es auch schon über zehn Jahre alt.
So wie es Embedded-Entwickler gibt, die niemals über ihren C- und
Assembler-Tellerrand hinausschauen werden, gibt es auch unbelehrbare
Webfuzzis, die sich einbilden, dass ihr aufgeblähtes Web-Toolkit alle
Einsatzgebiete erschlagen könne. Ich hatte einmal einen Kunden, der
einen Diplom-Informatiker eingestellt hatte, um die Firmware für einen
sehr kleinen LPC21xx zu schreiben. Allerdings lief die Firmware nicht,
und er zeigte mir ganz stolz sein riesiges objektorientiertes Framework.
Ich wies darauf hin, dass sein Microcontroller nur 2 KB Flash habe. Er
bestand darauf, dass es sich dabei um einen Druckfehler im Datenblatt
handelte, denn niemand wäre schließlich so blöd, einen Microcontroller
mit derart kleinem Speicher zu bauen. In Wirklichkeit wären es natürlich
2 MB. Das von ihm verwendete Flash-Programm hatte keine interne
Größenbeschränkung für Firmware-Updates. Das fertige Produkt kam
übrigens nie auf den Markt.
Andreas S. schrieb:> Ich hatte einmal einen Kunden, der> einen Diplom-Informatiker eingestellt hatte
Deppen gibt's überall... Ich kenne auch E-Techniker die für alles und
jedes (billige China-) Arduinos verbauen um dann festzustellen dass das
Konzept "einfacher Mikrocontroller plus alle Peripherie auf externen
Modulen" auch nicht das Beste ist, vor allem wenn die dann nötigen
Bibliotheken nicht gut sind.
Ein von uns beauftragtes Ing-Büro wollte das Problem, dass unser
Embedded-Linux-System "versehentlich" über den USB-Port mit dem PC
verbunden werden kann (was eigentlich nur für den Service vorgesehen
ist) lösen, indem sie die Datenleitungen weglassen und so auch im
Service das Flashen/Debuggen verhindern. Ich habe dann darauf
hingewiesen dass man unter Linux einfach die USB-Treiber weglassen
kann...
Andreas S. schrieb:> Allerdings lief die Firmware nicht,> und er zeigte mir ganz stolz sein riesiges objektorientiertes Framework.
Vielleicht habt ihr auch einfach jemanden mit dem falschen Fachgebiet
eingestellt. Manche denken ja "Informatiker" heißt "kann alles was mit
IT zu tun hat".
Dr. Sommer schrieb:> Interessant, hast du ein Beispiel? Das kann eigentlich nur sein, wenn> die handgestrickte Lösung irgendwelche fall-spezifischen Optimierungen> hat.
Ist eine Weile her, den Code kann ich nicht ausgraben, aber so im
Groben: Da anstatt echten Pointern für die Objekte Indices angelegt
werden, wird entsprechend auch ein Iterator für den Smart Pointer
generiert. Dafür wurde für jeden Iterator zum zugehörigen Objekttyp
zusätzlicher Code erzeugt. Dasselbe Ding mit dynamischen Datentypen (vom
Kernel bereitgestellt) macht in C weniger Overhead (Platz,
Code-Effizienz nahezu gleichauf).
Es gab da auch Unterschied betr. CPU-Architektur, die nur in C-Stil
wirklich portabel und explizit (ohne inline asm) umgesetzt werden
können).
Da entscheide ich mich dann für das minimale Subset.
Dr. Sommer schrieb:> Ich habe in C++ schon erfolgreich Kernel geschrieben und mich gefreut,> wie schön man die Datenstrukturen in Klassen packen kann.
Ich meine einen kompakten OS-Kernel, verifizierbar. Was im Sinne von
Linux, NuttX, FreeRTOS, usw. U.U. mit impliziter Haftung für fehlerfreie
Ausführung.
Dr. Sommer schrieb:> Ja, die Sachen die aus C übernommen wurden...
Haha. Schön wär's. Sicher gibt's Klimmzüge betr. C-Referenzen, aber es
wurde eine Menge verschlimmbessert, die genau dazu führt, dass
High-Level-Informatiker das Gefühl haben, C++-Code wäre mit seiner
Implizitheit fehlerfrei zu schreiben und dann noch wunderschön
abstrahiert. Genau das ist bei Safety fehl am Platz.
Dr. Sommer schrieb:> Im Gegenteil sind die Einführungen zu modernen Sprachen viel> zugänglicher als C. Jeder Anfänger fragt sich was dieses kryptische> "char* argv[]" heißen soll...
Und genau da ist das Problem: Man muss mal den Prototyping-Charakter
von C verstanden haben, sonst kapiert man nicht, was auf unterem Level
bei C++ passiert, und kann es auch nicht debuggen. Da muss ein Anfänger
durch.
Ich mache jetzt seit 20 Jahren Code-Analysen und muss leider sagen, dass
im Gros der schlimmste unwartbare (aber natürich schöne!) Code in Form
von C++ vorlag. Wegschmeissen, neu schreiben war jeweils billiger -
schlussendlich zählt einfach die Hausnummer, und nicht der
Wohlfühlfaktor. Da muss ich Olaf recht geben.
Olaf schrieb:> Und selbst wenn nicht, du hast dann> immer noch 3-5 Ingenieure in deinem Team die 1990 angefangen haben und> deine neue Modesprache nicht koennen. Aber die sind auch unverzichtbar> weil sie die Erfahrung mitbringen die fuer ein Embedded-Projekt> notwendig ist.
Da kann man argumentieren, dass die ja die neue Modesprache schnell
lernen könnte, wenn sie deutliche Vorteile aufweist. Der Punkt ist aber:
die Fehlersuche (und ins-knie-schiessen) will man unbedingt gegenüber
der herkömmlichen Methode minimiert sehen. Und es braucht mindestens
einen teamfähigen Experten, der den anderen den Weg ebnet und sie
anleiten kann.
Das ist bei Python eigentlich optimal, da ist immerhin das OO-Konzept
wirklich logisch umgesetzt.
Insofern hat sich auch bisher keiner wirklich geweigert, gelieferte
Python-Module und Scripte zu benutzen oder anzupassen.
Nur ist halt bei Python schwierig bis unmöglich, ein Compilat nach
Safety-Kriterien zu verifizieren, ausser man macht gleich Hardware draus
(MyHDL).
So wird hier Python also meistens nur als Prototyping-/Test-Umgebung
genutzt und der Prototyp wieder in ein C-Modul verfrachtet, damit's auch
auf dem uC läuft.
Ansonsten: Nix gegen C++ im Userspace, OO kann man auch sinnvoll
betreiben. Nur manche Schmankerl der std:: sind auf gewissen Systemen
pures implizites Gift und haben auch schon gehörigen Schaden
angerichtet, weil die Programmierer nicht wussten, dass da irgendwo ein
"realloc()" aufgerufen wird (und was es überhaupt macht).
Olaf schrieb:> BTW: Ich warte immer noch darauf das Smalltalk alle anderen Sprachen> abloesst weil das jetzt die neue coole Sau im Dorf ist. Ich kann mich> noch gut erinnern wie mir das um 2000 jeder erzaehlt hat.
Irgendwie war's seiner Zeit auch voraus, aber jetzt haben wir ja Python.
Aber warum nicht, gerade für den IoT Hype liesse sich Smalltalk sicher
aufwärmen. Forth schafft es ja auch immer mal wieder an die Oberfläche..
> Vielleicht habt ihr auch einfach jemanden mit dem falschen Fachgebiet> eingestellt.
Ich habe eher den Eindruck als wenn die Komplexizitaet der Produkte
heute so gross geworden ist das es selbst von sehr guten Teams wo alles
perfekt laeuft nur noch in Ausnahmefaellen perfekt hinbekommen wird. Und
sobald dann eine Kleinigkeit schief laeuft wird es dann sehr schnell
sehr boese.
Und das ist natuerlich ein weitere Grund warum es neue Sprachen schwer
haben. Wer will denn das Risiko eingehen das hinterher alle mit dem
Finger auf einen zeigen wenn es schief geht.
Olaf
Strubi schrieb:> Dafür wurde für jeden Iterator zum zugehörigen Objekttyp> zusätzlicher Code erzeugt.
Wenn der Iterator jeweils unterschiedliche Dinge tut bleibt das nicht
aus. Eine handgestrickte Lösung muss ja auch pro Typ was anderes tun.
Wenn der erzeugte Code für die unterschiedlichen Iterator-Typen gleich
ist, das template hier nur zwecks Typsicherheit benutzt wird (ähnlich
Java Generics), dann ist wohl der Compiler zu alt/schlecht um dies zu
bemerken. Man kann sich hier mit manueller Type Erasure behelfen, und
das template nur als dünnen typisierten Wrapper um nicht-typisierten
allgemeinen Code verwenden.
Strubi schrieb:> Ich meine einen kompakten OS-Kernel
Ich auch.
Strubi schrieb:> verifizierbar
Formale Verifikation a la L4? Ok, das gibt's für C++ nicht. Liegt aber
nicht an C++ selbst, nur an fehlenden Tools.
Strubi schrieb:> aber es> wurde eine Menge verschlimmbessert, die genau dazu führt, dass> High-Level-Informatiker das Gefühl haben, C++-Code wäre mit seiner> Implizitheit fehlerfrei zu schreiben und dann noch wunderschön> abstrahiert.
Was auch immer das heißen soll.
Strubi schrieb:> Da muss ein Anfänger> durch.
Ja, aber dann hat das noch mehr Elfenbein-Charakter als die
Modesprachen.
Strubi schrieb:> Ich mache jetzt seit 20 Jahren Code-Analysen und muss leider sagen, dass> im Gros der schlimmste unwartbare (aber natürich schöne!) Code in Form> von C++ vorlag.
Unwartbar durch Nicht-C++-Programmierer vielleicht... Ich habe auch
schon sehr viel furchtbaren C-Code gesehen und mir gewünscht, dass die
Leute vielleicht ein paar Paradigmen von den Modesprachen übernommen
hätten.
Strubi schrieb:> Nur manche Schmankerl der std:: sind auf gewissen Systemen> pures implizites Gift
Manche Schmankerl aus stdlib.h auch. Bei C und C++ muss man wissen,
welche Dinge man nicht nutzen sollte.
Strubi schrieb:> weil die Programmierer nicht wussten, dass da irgendwo ein> "realloc()" aufgerufen wird (und was es überhaupt macht).
Da gibt's ne ganz einfache Abhilfe: _sbrk nicht definieren, dann gibt's
Linker-Fehler wenn man versehentlich malloc verwendet...
Dr. Sommer schrieb:> Vielleicht habt ihr auch einfach jemanden mit dem falschen Fachgebiet> eingestellt. Manche denken ja "Informatiker" heißt "kann alles was mit> IT zu tun hat".
Nicht "ihr", sondern der Kunde.
Der Chef hatte mich beauftragt, ein "kleines" Hardwareproblem zu
beheben, das tatsächlich auch bestand. Er selbst hatte von Elektronik
und insbesondere Firmware so wirklich gar keine Ahnung. Nachdem ich dann
auch noch die Sache mit der "etwas" zu großen Fimrware aufgeklärt hatte,
wusste er nicht, wie er sich entscheiden sollte. Also durfte sein
Mitarbeiter weiter herumprogrammieren.
Als ich längere Zeit später aus Neugierde auf die Webseiten des
Unternehmens schaute, war dort das schon längst angekündigte Produkt
nicht mehr zu finden.
Strubi schrieb:> Dr. Sommer schrieb:>> Interessant, hast du ein Beispiel? Das kann eigentlich nur sein, wenn>> die handgestrickte Lösung irgendwelche fall-spezifischen Optimierungen>> hat.>> Ist eine Weile her, den Code kann ich nicht ausgraben, aber so im> Groben: Da anstatt echten Pointern für die Objekte Indices angelegt> werden,
Wer legt "Indices" statt "echten Pointer" an und was ist damit genau
gemeint?
> wird entsprechend auch ein Iterator für den Smart Pointer> generiert.
Jetzt gehts plötzlich um "Smart Pointer"? Wieso ein Iterator für Smart
Pointer?
> Dafür wurde für jeden Iterator zum zugehörigen Objekttyp> zusätzlicher Code erzeugt. Dasselbe Ding mit dynamischen Datentypen (vom> Kernel bereitgestellt) macht in C weniger Overhead (Platz,> Code-Effizienz nahezu gleichauf).
Was genau sind jetzt "dynamische Datentypen" die vom Kernel
bereitgestellt werden?
> Es gab da auch Unterschied betr. CPU-Architektur, die nur in C-Stil> wirklich portabel und explizit (ohne inline asm) umgesetzt werden> können).
Was genau ist damit jetzt gemeint?
> Da entscheide ich mich dann für das minimale Subset.Strubi schrieb:> Prototyping-Charakter von C verstanden haben
Du meinst Variablendefinition oder -deklaration?
Nachdem ich deinen Beitrag mehrfach gelesen habe, gehe ich davon aus,
dass du kein C++ kannst. Der Beitrag besteht aus einem Haufen
zusammengewürfelter Schlagwörter, die zusammen keinen Sinn ergeben. Es
gibt auch kein konkretes Beispiel oder sachliches Argument.
Dr. Sommer schrieb:> Wenn der erzeugte Code für die unterschiedlichen Iterator-Typen gleich> ist, das template hier nur zwecks Typsicherheit benutzt wird (ähnlich> Java Generics), dann ist wohl der Compiler zu alt/schlecht um dies zu> bemerken. Man kann sich hier mit manueller Type Erasure behelfen, und> das template nur als dünnen typisierten Wrapper um nicht-typisierten> allgemeinen Code verwenden.
Ein '*it' sollte nur aus einem 'Smart Pointer' (Pool-Nummer und
Objekt-Index) einen Pointer machen. D.h. dieselbe Operation (ausg. Cast
und sizeof(Objekt)) für alle Objekttypen.
Müsste eine gcc 3.x gewesen sein. Ich hätte auch erwartet, dass der
Compiler erkennt, dass das mit genau einem Wrapper (index -> Pointer)
abgehakt werden kann.
Nu, OO in C tut nicht so weh:
1
struct gna {
2
LIST_HEADER
3
Bla bla;
4
};
Und für die Iteratoren muss man halt Makros nehmen.
Dr. Sommer schrieb:> Unwartbar durch Nicht-C++-Programmierer vielleicht...
Leider nein. Undebugbar durch C++-Programmierer. Sozusagen in letzter
Instanz.
mh schrieb:> Nachdem ich deinen Beitrag mehrfach gelesen habe
Dann liest du es eben noch ein paarmal durch, bis du es kapiert hast.
Ein gewisses Bildungsniveau darf man erwarten, eine Antwort auf
Trollgeunke nicht.
Strubi schrieb:> Müsste eine gcc 3.x gewesen sein.
Also vor ewigen Zeiten...
Strubi schrieb:> Ich hätte auch erwartet, dass der> Compiler erkennt, dass das mit genau einem Wrapper (index -> Pointer)> abgehakt werden kann.
Kann es eigentlich auch. Dann wurde irgendwas falsch gemacht.
Strubi schrieb:> Nu, OO in C tut nicht so weh:
Und das dann für jeden Listen-Typ? Tut überhaupt nicht weh, nein...
Strubi schrieb:> Leider nein. Undebugbar durch C++-Programmierer. Sozusagen in letzter> Instanz.
Na, schlechten Code kann man in jeder Sprache produzieren. Ich habe
meine C++-Fehler noch immer gefunden.
Strubi schrieb:> Wie sieht das in der Praxis aus, macht das engineering-mässig Sinn, ein> Mikro-Kernel in C zu schreiben und einen Applikations-Layer in Rust> drüberzukleben?
Ob es Sinn macht den Unterbau in C zu schreiben kommt meiner Meinung
nach darauf an wie viel legacy-Code Verwendung finden soll.
Strubi schrieb:> D.h. wie einfach ist es, ein Objekt mit einem Listen-Kopf (C-Struct mit> .next, .prev, .children und einer Objekt-Nutzlast) zu wrappen?
Das ist sehr einfach, weil es dafür in Rust ein FFI gibt und man "rust
bindgen" lediglich mit dem C-Header füttern muss um einen Rust-Wrapper
um irgendeine beliebige C-Library zu bekommen.
https://github.com/rust-lang/rust-bindgen/blob/master/README.mdStrubi schrieb:> Wie sieht es mit valgrind aus, kann man das (mit Debug-Symbolen) schon> sinnvoll verwenden?
Zur Kombination von Rust und Valgrind kann ich nichts sagen aber die
meisten Memory-Bugs werden vom Rust-Compiler gar nicht erst zugelassen.
Strubi schrieb:> Und wie gehn coverage-Tests (gcov?) von der Hand?
Es gibt ein Pendant namens grcov, welches selber von Mozilla genutzt
wird. Benutzt habe ich es persönlich noch nicht:
https://github.com/mozilla/grcov/blob/master/README.md
Dr. Sommer schrieb:> Strubi schrieb:>> Nu, OO in C tut nicht so weh:>> Und das dann für jeden Listen-Typ? Tut überhaupt nicht weh, nein...
Nutze selber gerne C++, aber wenn die Rahmenbedingungen C verlangen ist
auch das OK. C11 _Generic hast du gesehen? Dazu ein mehrfach
includierbares header file mit ein paar Macros fürs Tokenpasting.
Fertig.
Ein template ist ja letztendlich auch nichts anderes.
Michael schrieb:> Ein template ist ja letztendlich auch nichts anderes.
Ein Template kann viel mehr als schnöde Textersetzung, wie durch
Mehrfach-Include-Tricks.
_Generic ist nur ein Ersatz für Funktions Overloads, nicht für
Templates ("Generics"). Der Name ist halt total dämlich gewählt. Das ist
im Endeffekt manuelles Name Mangling.
Dr. Sommer schrieb:> Michael schrieb:>> Ein template ist ja letztendlich auch nichts anderes.>> Ein Template kann viel mehr als schnöde Textersetzung, wie durch> Mehrfach-Include-Tricks.> _Generic ist nur ein Ersatz für Funktions Overloads, nicht für> Templates ("Generics").
Klar. (Partielle) Spezialisierung, SFINAE, ...
> Der Name ist halt total dämlich gewählt. Das ist> im Endeffekt manuelles Name Mangling.
Schon klar, aber daher nannte ich ja auch macros und tokenpasting. Als
Beispiel soll etwa so ein Ring-Buffer mit unterschiedlich breiten
Indextypen ersetzt werden:
1
template<typenameT>
2
classRing
3
{
4
public:
5
Ring(ring_size_tcap);
6
boolEnqueue(constuint8_t*src,ring_size_tlen);
7
// instead of return bool, maybe exception also possible
8
// more methods
9
private:
10
Trd_back;
11
Twr_front;
12
Tsize;
13
constTcapacity;
14
uint8_tdata[];
15
};
ring.h:
1
#ifndef RING_H
2
#define RING_H
3
4
// Instantiate all functions for 8 bit and 16 bit sized counters/indices.
5
6
#define RING_WIDTH 8
7
# include "ring_impl.h"
8
#undef RING_WIDTH
9
10
#define RING_WIDTH 16
11
# include "ring_impl.h"
12
#undef RING_WIDTH
13
14
// We use C11's _Generic keyword to automagically resolve, for example,
15
// ring_enqueue() to ring8_enqueue() or ring16_enqueue(), depending on the
16
// type of the first parameter (ring8_t* or ring16_t*).
Michael schrieb:> Ist natürlich mehr Schreibaufwand als in C++, aber wenn der Rest alles C> ist und ich nur den Ringbuffer benötige, werde ich nicht auf C++> umschwenken.
Warum nicht? Die _Generic Wrapper könnten ja den C++ Code aufrufen. Dann
kann der restliche Code C bleiben.
Wer auf Biegen und Brechen C für Dinge nutzt, für die explizit C++
geschaffen wurde, bearbeitet auch Schrauben mit dem Hammer...
Dr. Sommer schrieb:> Michael schrieb:>> Ist natürlich mehr Schreibaufwand als in C++, aber wenn der Rest alles C>> ist und ich nur den Ringbuffer benötige, werde ich nicht auf C++>> umschwenken.>> Warum nicht? Die _Generic Wrapper könnten ja den C++ Code aufrufen. Dann> kann der restliche Code C bleiben.>> Wer auf Biegen und Brechen C für Dinge nutzt, für die explizit C++> geschaffen wurde, bearbeitet auch Schrauben mit dem Hammer...
Ich bin nur sehr vorsichtig, C und C++ zu mischen. Das ohne undefined
behaviour hinzubekommen ist eine Kunst. Man denke z.B. an Exceptions,
die zurück nach C geworfen werden. Ein einfaches "extern "C"" bzw.
"extern "C++"" genuegt da nicht.
Michael schrieb:> Man denke z.B. an Exceptions, die zurück nach C geworfen werden. Ein> einfaches "extern "C"" bzw. "extern "C++"" genuegt da nicht.
Ja, da muss man Rückgabewerte verwenden. Immer noch besser als das
Gewürge mit dem Präprozessor.
Dr. Sommer schrieb:> Michael schrieb:>> Man denke z.B. an Exceptions, die zurück nach C geworfen werden. Ein>> einfaches "extern "C"" bzw. "extern "C++"" genuegt da nicht.>> Ja, da muss man Rückgabewerte verwenden. Immer noch besser als das> Gewürge mit dem Präprozessor.
Man muss vor allem die Exceptions fangen bevor man sie auf einen
Rückgabewert zurückführen kann.
Meine nur: C und C++ zu mischen ist extrem heikel. Sind halt komplett
verschiedene Sprachen mit dem gleichen ersten Buchstaben, mehr nicht.
Es klappt eigentlich nur, weil GCC über die eigentlichen Sprachstandards
hinaus gehende Garantien macht. Aber zwei durch unterschiedliche
Compiler erstellte Kompilate kombinieren (z.B. Library + Programm) wird
formell fast immer UB sein.
In der Praxis funktioniert das schon, aber wenn man den Standards folgt
ist es quasi unmöglich.
Michael schrieb:> Ich bin nur sehr vorsichtig, C und C++ zu mischen. Das ohne undefined> behaviour hinzubekommen ist eine Kunst. Man denke z.B. an Exceptions,> die zurück nach C geworfen werden. Ein einfaches "extern "C"" bzw.> "extern "C++"" genuegt da nicht.
Das ist genau der Punkt, an dem Coverage-Tests (im Simulator) mit C++
versagen und der Compiler auch mal 'toten Code' generieren kann. Das ist
dann auch extrem mühsam zu debuggen. Da habe ich lieber eine saubere
Cleanup-Funktion die manuell explizit aufräumt (switch(state) { case:
...} ). Da sieht man sofort, in welchem (Fehler-)Zustand das System ist,
und kann nachweisen, dass zu allen Fehlerzuständen X die Aufräumprozedur
ihren Job richtig macht. Manche Kunden erwarten das auch explizit so in
der Code-Review.
Es ist schlussendlich das alte Lied: Wenn man alles an C++ abstellt, was
problematisch ist, kann man auch C nehmen. Oder Ada. Das Mehr an
Schreibarbeit zahlt sich spätestens beim expliziten Debuggen (was bei
Templates a la Boost-Murks schon ein Albtraum werden kann) aus.
Michael schrieb:> Meine nur: C und C++ zu mischen ist extrem heikel.
Dass C++ abwärtskompatibel zu C ist, ist ja eigentlich kein Zufall...
Die Standard Bibliothek ist ja auch großteils C.
Strubi schrieb:> Wenn man alles an C++ abstellt, was problematisch ist, kann man auch C> nehmen
Also genau alles von C++ ist problematisch? Auch sowas wie richtige
Konstanten statt Makros?
Strubi schrieb:> Das Mehr an Schreibarbeit zahlt sich spätestens beim expliziten Debuggen> (was bei Templates a la Boost-Murks schon ein Albtraum werden kann) aus.
Das ist ja genau der Witz. Weil der C++ Compiler strenger Typen prüfen
und Fehler finden kann, muss man weniger Debuggen. Deswegen kommen C
Programmierer mit C++ auch nicht klar - wenn der Compiler sich beschwert
dass man einen int in einen std::vector<std::string> packen möchte, ist
er sauer, weil er das Programm nicht übersetzen und starten kann... um
genau diesen Fehler suchen zu können.