mikrocontroller.net

Forum: Compiler & IDEs Gibt es das in C oder C++ nicht?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Mariella M. (mauriella)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein Ausschnitt aus einem Artikel

"In vielen Programmiersprachen stehen Programmierern eine Reihe von 
vordefinierten Ganzzahltypen zur Verfügung, die zum Beispiel 8, 16, 32 
und 64 Bit einnehmen (in der Regel gibt es noch Varianten mit oder ohne 
Vorzeichen). Andere Wertebereiche sind nicht möglich.
In Pascal hingegen können Programmierer ihre eigenen Ganzzahltypen 
völlig frei definieren, so dass sie am besten zum Anwendungsbereich 
passen. Ist zum Beispiel ein Winkel in Grad gefragt, kann der Typ so 
definiert werden:

          Type Angle is range 0 .. 359;

Werte außerhalb dieses Bereichs sind für Variablen dieses Typs nicht 
zulässig. Eine Zuweisung, die diese Eigenschaft verletzen würde, zum "


oder

"Eines der Probleme der Embedded-Programmierung ist, dass einerseits 
hardwarenahe Programmierung und bitgenaue Auslegung der Daten nötig 
sind, andererseits solche Details eigentlich einfachen Code umständlich 
und fehleranfällig machen. Die Antwort auf dieses Problem in Ada sind 
Representation Clauses. Diese ermöglichen es, die bekannten 
Datenstrukturen wie Arrays und Records wie gewünscht im Speicher 
auszulegen und sie effizient und einfach zu benutzen. Ein einfaches 
Beispiel wäre:

          Type BitArray is array (1 .. 8) of Boolean
          with Size => 8;
              Pragma Pack(BitArray);

In C kann man zwar auch ein Byte für ein solches Array reservieren. Um 
damit umzugehen, sind dann aber Bitmasken und Bitshifts nötig - dies ist 
fehleranfällig und verschleiert, dass der Code einfach nur ein Array 
manipuliert. In Ada können solche Arrays wie oben definiert im Weiteren 
ganz normal verwendet werden - mit Zugriff auf jeden beliebigen Index. 
Der Compiler generiert automatisch den korrekten Code. Representation 
Clauses ermöglichen noch viel mehr, als dieses einfache Beispiel zeigt, 
und sind ein unverzichtbares Werkzeug für hardwarenahe 
Ada-Programmierer.

"

:
Autor: nfet (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In C ist beides meines Wissens nach so nicht möglich.
In C++ ist beides genauso möglich.

Autor: Oliver S. (oliverso)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
nfet schrieb:
> In C++ ist beides genauso möglich.

Wobei "genauso" nicht ganz wörtlich zu nehmen ist. Die Sprachdefinition 
selber bietet das nicht, man muß sich dafür schon ein paar dutzend 
Zeilen (Template-)Code zusammenbasteln.

Oliver

Autor: Random .. (thorstendb) Benutzerseite
Datum:

Bewertung
2 lesenswert
nicht lesenswert
Pascal wird das auch nur auf einen INT mit if(range...) Begrenzung 
abbilden. Das ließe sich in C++ durch Überladen der Operatoren 
nachbilden.

: Bearbeitet durch User
Autor: Dynamo (Gast)
Datum:

Bewertung
-2 lesenswert
nicht lesenswert
Naja, die Frage ist natürlich, ob die Sprache Verletzungen der 
Typkonventionen zur Laufzeit abfängt. Wenn also eine Variable auf den 
Wertebereich 0-359 beschränkt ist, kann der Compiler sehr wohl 
feststellen, ob bei einer *statischen" Zuweisung der Wertebereich 
eingehalten wird. Aber wenn dann zur Laufzeit eine Manipulation dieser 
Variable den Wertebereich verletzt, braucht es schon SEH, um das 
abzufangen. Und SEH in Embedded ist so eine Welt für sich, abgesehen 
davon, dass es den Entwickler ja nicht davon befreit, die exception auch 
im Rahmen des Gesamtcodes sinnvoll abzuhandeln.

M.E. nach wird der statischen Codeanalyse viel zu viel Wert beigemessen 
(s. MISRA). Da werden ganze Jobs dafür abgestellt, damit irgendwo ein 
Schlips einen Compliancestempel unter ein Dokument drücken kann, und 
alle glauben, dass der Code damit funktioniert. Würde mich mal 
interessieren, ob es darüber verlässliche Studien gibt, wieviele 
Softwarekosten durch zur Laufzeit anfallende Fehler anfallen, und ob der 
Aufwand für statische Analysen wirklich gerechtfertigt ist.

Nicht dass man statische Codeanalysen nicht machen sollte; linten und 
Warnungen eliminieren ist immer eine gute Praxis. Aber wenn der Aufwand 
für diese Analysen exponentiell wächst und der Entwickler sich deswegen 
nicht um das Testen des Laufzeitverhaltens kümmern kann, ist irgendwas 
schief gelaufen.

Autor: mh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was ist SEH?

Autor: Oliver S. (oliverso)
Datum:

Bewertung
3 lesenswert
nicht lesenswert
Dynamo schrieb:
> abgesehen
> davon, dass es den Entwickler ja nicht davon befreit, die exception auch
> im Rahmen des Gesamtcodes sinnvoll abzuhandeln.

Das Problem ist aber völlig unabhängig von der Programmiersprache. Was 
man in embedded mit solch einer Werteverletzung dann macht, ist sehr 
applikationsabhängig. Man kann die Mondrakete natürlich mal eben neu 
booten ;)

Oliver

Autor: Mariella M. (mauriella)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
"Naja, die Frage ist natürlich, ob die Sprache Verletzungen der
Typkonventionen zur Laufzeit abfängt."

JEPP, tut sie, darum geht es ja beim Faktor Sicherheit;-)

Autor: A. F. (artur-f) Benutzerseite
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
> Type Angle is range 0 .. 359;
Gibt es nicht in C, kann man aber nur mit einer if-Abfrage lösen.


>Type BitArray is array (1 .. 8) of Boolean
>          with Size => 8;
>            Pragma Pack(BitArray);

Bitfelder gibt es dagegen auch in C.

struct MyByte
{
    int Bit7: 1;
    ....
    int Bit0: 1;
}

Autor: Dynamo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mh schrieb:
> Was ist SEH?

Sorry, Structured Exception Handling.

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. F. schrieb:
> Bitfelder gibt es dagegen auch in C.

Deren Speicherlayout ist aber Plattform-abhängig; darauf kann man sich 
nicht verlassen.

Mit C++ und Templates kann man sich Bibliotheken bauen, die das portabel 
auf Basis von bitweisen Operationen machen, wie meine:
https://github.com/Erlkoenig90/uSer

Autor: Yalu X. (yalu) (Moderator)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
In C++ gibt es gepackte Bit-Arrays (std::vector<bool>).

Autor: Vincent H. (vinci)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Yalu X. schrieb:
> In C++ gibt es gepackte Bit-Arrays (std::vector<bool>).

https://en.cppreference.com/w/cpp/utility/bitset

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
4 lesenswert
nicht lesenswert
Dynamo schrieb:
> M.E. nach wird der statischen Codeanalyse viel zu viel Wert beigemessen
> (s. MISRA). Da werden ganze Jobs dafür abgestellt, damit irgendwo ein
> Schlips einen Compliancestempel unter ein Dokument drücken kann, und
> alle glauben, dass der Code damit funktioniert.

MISRA ist doch eher ein Set von Coding-Rules, das würde ich jetzt nicht 
als statische Analyse bezeichnen.  Statische Analyse: Diagnostics 
(Fehler, Warnungen,...) der Tools, Lint, abstrakte Analyse, 
Code-Coverage, Profiling, etc.

Aber wer macht schon abstrakte Analyse?  Luftfahrt, Nukleartechnik ok. 
Aber was z.B. Automotive teilweise an Code und Paradigmen so 
abliefert...

MISRA ist nicht mehr als ein bisschen Feenstaub.  Heißt jetzt nicht, 
dass es keine verbindlichen Coding-Rules geben sollte, sowohl was 
Textlayout als auch Verwendung von Sprachfeatures angeht finde ich das 
wichtig.  Aber der Rummel um MISRA soll vielleicht auch darüber 
hinwegtäuschen, dass es nicht viel mehr als ein Feigenblatt ist.

Vorteil an MISRA ist eben, dass es einfach abzupfüfen und "stempelbar" 
ist: Liste abgehakt, Feen^H^H^H^HStempel drauf, fertig.

> Nicht dass man statische Codeanalysen nicht machen sollte; linten und
> Warnungen eliminieren ist immer eine gute Praxis. Aber wenn der Aufwand
> für diese Analysen exponentiell wächst und der Entwickler sich deswegen
> nicht um das Testen des Laufzeitverhaltens kümmern kann, ist irgendwas
> schief gelaufen.

Wichtig ist, möglicht viele Dinge sinnvoll zu kombinieren.  Beispiel: Es 
wird viel Aufwand in Testing gesteckt bei nicht-adäquatem Reviewing, 
dann tritt ein Qualitätsproblem auf.  Nicht selten ist der Reflex, 
Testing weiter auszubauen aber die Schwachstellen (Reviewing) zu 
belassen.

Wie es so schön heißt: Qualität lässt sich nicht in Code "hineintesten".

Testing ist einfach skalierbar: Es wird einfach 10% mehr getestet und 
geglaubt, der Code sei 10% robuster (was immer das heißen soll). Mit 
Reviewing ist es nicht so simpel:  Man braucht Entwickler, die sehr 
erfahren sind, am besten über dem Problem stehen, aber den Code nicht 
selbst implementiert haben.  Das lässt sich nicht schnell mal skalieren, 
indem man die Anzahl der dafür wenig qualifizierten Reviewer erhöht.

Oder beim Testing wird gefordert, dass ein Entwickler keine Tests für 
Code schreiben darf, den er selbst entwickelt oder zu dem er beigetragen 
hat. Ziemlicher Unsinn.  Warum sollte man Whitebox-Testing verbieten? Es 
ist ein anderes Werkzeug zur Qualitätssicherung als Blackbox-Testing, 
und es kategorisch auszuschließen oder als unnötig zu erachten, vergibt 
einfach Chancen.

Hat ne Zeit gedauert, biss ich begriffen hatte, dass es bei 
Qualitätsmanagement nicht darum geht, die Qualität von irgendwas zu 
verbessern oder zu sichern, sondern darum, auf Teufel-komm-raus 
irgendwelche starren Prozesse zu installieren und über teure Tools 
darzustellen damit es "stempelbar" wird.  Egal wieviel Reibungsverluste 
und Overhead das produziert oder die Qualität sogar verschlechtert.

Autor: Jörg W. (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Niklas G. schrieb:
>> Bitfelder gibt es dagegen auch in C.
>
> Deren Speicherlayout ist aber Plattform-abhängig; darauf kann man sich
> nicht verlassen.

Das erste stimmt, das zweite nicht: selbstverständlich kann man sich 
darauf verlassen, denn es ist halt "implementation-defined", aber nicht 
"undefined".

Da realer Code auf einer konkreten Implementierung läuft, kann man sich 
in diesem Rahmen schon drauf verlassen – auch, wenn es nicht portabel 
ist. Wenn ich damit aber bspw. die Steuerregister meines Controllers 
beschreibe, würde irgendeine Portabilität sowieso nicht helfen.

Allerdings scheint ein Bitfeld geringfügig anders zu funktionieren als 
die Ada-Lösung, denn dort steht etwas von "Adressierung als Index".

Autor: Dynamo (Gast)
Datum:

Bewertung
-2 lesenswert
nicht lesenswert
Oliver S. schrieb:
> Dynamo schrieb:
>> abgesehen
>> davon, dass es den Entwickler ja nicht davon befreit, die exception auch
>> im Rahmen des Gesamtcodes sinnvoll abzuhandeln.
>
> Das Problem ist aber völlig unabhängig von der Programmiersprache. Was
> man in embedded mit solch einer Werteverletzung dann macht, ist sehr
> applikationsabhängig. Man kann die Mondrakete natürlich mal eben neu
> booten ;)
>
> Oliver

Klar, aber das wird in der Regel nicht verstanden. Wenn eine 
Programmiersprache zur Compilezeit strict type checking durchführt, ist 
das Problem durch einen Compiler Error gegessen und kann statisch gefixt 
werden. Wenn die Laufzeitkomopnente der Sprache hingegen bei Verletzung 
der Konventionen eine exception generiert (anders kann es ja nicht 
gehen), ist das lediglich eine Unterstützung des Entwicklers. Ignoriert 
er/sie das Abhandeln der Exception, ist die Bandbreite der möglichen 
Folgeprobleme (und damit die fehlende Deterministik des Programmes) 
tupfengleich so wie bei einer Sprache, die das Ganze nicht unterstützt. 
Dahingegen der Aufwand der Implementation RTL seitig und damit der 
Footprint der SEH sehr gross.

Die Aussage, dass durch strict type checking automatisch robustere 
Software ensteht, ist also falsch.

Autor: Yalu X. (yalu) (Moderator)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
Was die Integer-Subranges betrifft:

Unter- und Überschreitungen des Wertebereichs können manchmal bereits
zur Compilezeit, meistens aber erst zur Laufzeit erkannt werden.

Die Laufzeitüberprüfung kann aber aus folgenden Gründen problematisch
sein:

- Sie kostet viel Rechenzeit, weil sie nach jeder noch so primitiven
  Rechenoperation durchgeführt werden muss. Dir Überprüfung erfordert
  4 Operationen, nämlich 2 Vergleiche und 2 bedingte Sprünge. Damit
  wird die Gesamtzahl der für einen Rechenschritt auszuführenden
  Operationen verfünffacht.

  Praktikabler ist es i.Allg., die Prüfung nur an kritischen Stellen im
  Programm durchzuführen. Das erfordert zwar etwas Handarbeit, dafür
  kann aber in vielen Fällen der erlaubte Wertebereich kontextabhängig
  stärker eingeschränkt werden als es bei der automatischen Prüfung
  möglich ist.

- In sicherheitskritischen Anwendungen ist zu dem Zeitpunkt, wo ein
  Wertebereichsfehler erkannt wird, das Kind oft schon längst in den
  Brunnen gefallen. Man denke z.B. an eine Herzlungenmaschine. Was soll
  die Software tun, wenn ein Fehler festgestellt wurde? Einfach
  abbrechen ist keine Option. Die Maschine kontrolliert herunterfahren
  und dann abbrechen schon zwar vielleicht die Maschine, nicht aber den
  Patienten. Das fehlerhafte Recheneregebnis auf gut Glück durch
  irgendeinen gültigen Wert zu ersetzen und das Programm fortzusetzen
  ist ebenfalls riskant.

Die Laufzeitprüfung kann in folgenden Fällen sinnvoll sein:

- während der Testphase, wodurch die Chance erhöht wird, einen Fehler zu
  erkennen, bevor die Software real zum Einsatz kommt

- bei Desktopsoftware, wo ein Programmabbruch im Fehlerfall relativ
  unkritisch ist und der Anwender gebeten werden kann, Informationen zum
  aufgetretenen Fehler an den Softwarehersteller zu schicken, um diesem
  die Fehlerbeseitigung zu erleichtern.

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg W. schrieb:
> selbstverständlich kann man sich
> darauf verlassen, denn es ist halt "implementation-defined", aber nicht
> "undefined".

Okay, man muss sagen "eingeschränkt verlässlich". Compiler-Optionen, 
-Updates können das Verhalten auch beeinflussen (z.B. "-mms-bitfields").

Yalu X. schrieb:
> Was soll
>   die Software tun, wenn ein Fehler festgestellt wurde?

Ein Fehlersignal setzen, sodass der 2. Kanal (hoffentlich) übernimmt - 
besser als nichts. Ist natürlich nur als zusätzliche Maßnahme zu 
verstehen und nicht als Lösung von Programmierfehlern.

Yalu X. schrieb:
> - Sie kostet viel Rechenzeit, weil sie nach jeder noch so primitiven
>   Rechenoperation durchgeführt werden muss.

Bei extrem sicherheitskritischen Systemen wird sowieso auch ohne 
Optimierung kompiliert, sodass vermutlich ohnehin ausreichend Reserve 
vorhanden ist.

Autor: Dynamo (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Yalu X. schrieb:
> Was die Integer-Subranges betrifft:
>
> Unter- und Überschreitungen des Wertebereichs können manchmal bereits
> zur Compilezeit, meistens aber erst zur Laufzeit erkannt werden.
>
> Die Laufzeitüberprüfung kann aber aus folgenden Gründen problematisch
> sein:
>
> - Sie kostet viel Rechenzeit, weil sie nach jeder noch so primitiven
>   Rechenoperation durchgeführt werden muss. Dir Überprüfung erfordert
>   4 Operationen, nämlich 2 Vergleiche und 2 bedingte Sprünge. Damit
>   wird die Gesamtzahl der für einen Rechenschritt auszuführenden
>   Operationen verfünffacht.
>

Ja. Dazu kommt, dass ohne Hardwareunterstützung die Prüfung 
unvollständig ist. Wenn also (z.B. durch Stacküberlauf) eine Variable 
übertrampelt wird und damit ihren Wertebereich über- oder 
unterschreitet, merkt das der Prüfcode nicht, weil er ja logischerweise 
nur an den Stellen aktiv ist, wo erlaubt auf die Variable zugegriffen 
wird.

>   Praktikabler ist es i.Allg., die Prüfung nur an kritischen Stellen im
>   Programm durchzuführen. Das erfordert zwar etwas Handarbeit, dafür
>   kann aber in vielen Fällen der erlaubte Wertebereich kontextabhängig
>   stärker eingeschränkt werden als es bei der automatischen Prüfung
>   möglich ist.
>

Ja, ist aber sehr fehleranfällig (vor Allem in verteilten Projekten) und 
ebenso unvollständig.

> - In sicherheitskritischen Anwendungen ist zu dem Zeitpunkt, wo ein
>   Wertebereichsfehler erkannt wird, das Kind oft schon längst in den
>   Brunnen gefallen. Man denke z.B. an eine Herzlungenmaschine. Was soll
>   die Software tun, wenn ein Fehler festgestellt wurde? Einfach
>   abbrechen ist keine Option. Die Maschine kontrolliert herunterfahren
>   und dann abbrechen schon zwar vielleicht die Maschine, nicht aber den
>   Patienten. Das fehlerhafte Recheneregebnis auf gut Glück durch
>   irgendeinen gültigen Wert zu ersetzen und das Programm fortzusetzen
>   ist ebenfalls riskant.
>
> Die Laufzeitprüfung kann in folgenden Fällen sinnvoll sein:
>
> - während der Testphase, wodurch die Chance erhöht wird, einen Fehler zu
>   erkennen, bevor die Software real zum Einsatz kommt
>
> - bei Desktopsoftware, wo ein Programmabbruch im Fehlerfall relativ
>   unkritisch ist und der Anwender gebeten werden kann, Informationen zum
>   aufgetretenen Fehler an den Softwarehersteller zu schicken, um diesem
>   die Fehlerbeseitigung zu erleichtern.

FULL ACK.

Autor: Marten Morten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
(Quoting korrigiert)

Mariella M. schrieb:
> Dynamo schrieb:
>> Naja, die Frage ist natürlich, ob die Sprache Verletzungen der
>> Typkonventionen zur Laufzeit abfängt.
>
> JEPP, tut sie, darum geht es ja beim Faktor Sicherheit;-)

Das hat bei der in Ada geschriebenen Software der Ariane 5 beim Flug 501 
trotzdem nicht geholfen. Sieben Variablen im Trägheitsnavigationssystem 
wurden von den Programmierern als Anfällig für Konvertierungsfehler 
identifiziert. Aus unbekannten Gründen wurden nur vier dagegen 
gesichert, drei nicht. Eine der ungesicherten lief bei einer 64-Bit 
Floating-Point nach 16-Bit Signed-Integer Konvertierung im Flug über und 
löste eine Exception aus.

Das Exeption-Handling war genau so implementiert wie es spezifiziert 
war: Prozessor Shutdown des Trägheitsnavigationssystems. Das hot-standby 
Backup-System war aus dem selben Grund sogar etwas früher in die Knie 
gegangen. Damit gab es kein funktionsfähiges Trägheitsnavigationssystem. 
Das war es dann für die Rakete.

Obendrein wurde der Fehlercode des Trägheitsnavigationssystems 
fälschlich als Steuerkommando interpretiert. Das beschleunigte das 
Auseinanderbrechen.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Niklas G. schrieb:
> Jörg W. schrieb:
>> selbstverständlich kann man sich
>> darauf verlassen, denn es ist halt "implementation-defined", aber nicht
>> "undefined".
>
> Okay, man muss sagen "eingeschränkt verlässlich". Compiler-Optionen,
> -Updates können das Verhalten auch beeinflussen (z.B. "-mms-bitfields").

Dass eine Option, die das ABI ändert, gerne zu einem anderen ABI führt, 
ist nicht wirklich ein Geheimnis.

Auch wenn ein std::vector<bool> portabel ist, ist er denn 
plattformunabhängig? Wenn ein std::vector<bool> von Host A nach Host B 
übertragen werden soll, wird man Serialisierung verwenden und nicht die 
interne Darstellung Byte für Byte übertragen.

Autor: Mariella M. (mauriella)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein Fehler ist es ebenfalls, zu einem Winkel von 359 Grad ein Grad zu
addieren, denn man würde ja den Wertebereich verlassen. Aber wäre es
nicht praktischer, wieder bei 0 Grad anzukommen? Das kann in Pascal als
auch in Ada mit sogenannten modularen Typen erreicht werden:

          Type Mod_Angle is mod 360;

Diese Deklaration definiert wieder einen Typ mit einem Wertebereich von
0 bis 359, jetzt werden aber Berechnungen mit diesem Typ modular
ausgeführt:

          X : Angle := 365;       --  das ist immer noch ein Fehler
          Y : Angle := 359;
          Y := Y + 1;                --  das ist OK, Y ist nun 0

Autor: Jörg W. (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Mariella M. schrieb:
> Das kann in Pascal als auch in Ada mit sogenannten modularen Typen
> erreicht werden:

Und jetzt bitte das Ganze für Radianten … :-)

Autor: Oliver S. (oliverso)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mariella M. schrieb:
> Type Mod_Angle is mod 360;

Auch da gilt für c++:

Oliver S. schrieb:
> Die Sprachdefinition
> selber bietet das nicht, man muß sich dafür schon ein paar dutzend
> Zeilen (Template-)Code zusammenbasteln.

Oliver

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mariella M. schrieb:
> Ein Fehler ist es ebenfalls, zu einem Winkel von 359 Grad ein Grad zu
> addieren, denn man würde ja den Wertebereich verlassen. Aber wäre es
> nicht praktischer, wieder bei 0 Grad anzukommen?

Das wird ganz auf die Anwendung ankommen.

Bei einem Roboterarm wird man nicht von 359° auf 0° springen wollen, da 
ist u.U. eine Saturierung sinnvoller, und es ich auch nicht egal, ob man 
bei 0° ist oder bei 360°:  0°+1°=1°, 360°+1°=360°.

Es gibt bestimmt auch Fälle, wo eine Fehlerbehandlung sinnvoller ist.

Allein hier haben wir also schon 3 verschiedene Szenarien:

1) Wrap-around mod 360
2) Saturierung
3) Fehler

> Das kann in Pascal als auch in Ada mit sogenannten modularen
> Typen erreicht werden:
>
>           Type Mod_Angle is mod 360;

Bei Winkeln wäre Float sinnvoller, d.h. ein Bereich [0,360) oder 
[-180,180).  Und bei echter modularer Arithmetik ist die Division 
ziemlich ungewohnt:

7*52° = 364° = 4°.  Daher ist 4°/7 = 52° und nicht etwa 0° :-)

sowas hat man z.B. bei Kryptosystemen (die natürlich nicht in ° 
rechnen), aber es verdeutlicht das Problem, dass das mit einem 
sprachgegebenen Typsystem schlecht abzubilden ist.

Ab besten abzubilden ist das mit selbst definierten Typen / Klassen und 
Overloading von Operatoren, Zuweisungen etc. wie in C++ oder D.

Damit lässt sich dann auch abbilden, dass es i.d.R. nicht sinnvoll ist, 
Winkel zu multiplizieren oder Winkel und Skalar (allgemein Größen 
inkompatibler Einheiten) zu addieren, zu subtrahieren oder zu 
vergleichen.

Autor: Tonja S. (Firma: SVK) (tonja_st)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zusammengefasst lässt sich also sagen.
Der C Programmierer versucht immer Ausflüchte zu finden, weshalb C nicht 
schlechter ist.
Selbst die beste Programiersprache wird so durch konstruierte Fehler, 
nicht von ihm als solche erkannt.
Fazit eines C Programmierera: Es ist immer der Dumme der das Programm 
schreibt, wer gut ist macht keine Fehler.

Somit ist es aus Sicht eines C Programmierer also völlig überflüssig 
eine neue Programmiersprache zu entwickeln um sicherer, fehlerfreier zu 
programmieren.

Fein:-)

Autor: Dynamo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tonja S. schrieb:
> Zusammengefasst lässt sich also sagen.
> Der C Programmierer versucht immer Ausflüchte zu finden, weshalb C nicht
> schlechter ist.
> Selbst die beste Programiersprache wird so durch konstruierte Fehler,
> nicht von ihm als solche erkannt.
> Fazit eines C Programmierera: Es ist immer der Dumme der das Programm
> schreibt, wer gut ist macht keine Fehler.
>
> Somit ist es aus Sicht eines C Programmierer also völlig überflüssig
> eine neue Programmiersprache zu entwickeln um sicherer, fehlerfreier zu
> programmieren.
>
> Fein:-)

Sorry, völliger Blödsinn.

Wenn es im Embedded Bereich eine Alternative zu C geben würde, die 
dieselbe Kontrolle über die Hardware und dieselben 
Optimierungsmöglichkeiten bei gleichem Footprint ohne die Probleme geben 
würde, wäre diese Sprache (nennen wir sie mal hypothetisch "D+++") schon 
längst State of the Art.

Autor: Peter D. (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich seh das auch so.
Ein Compiler kann nicht denken und daher dem Programmierer nicht das 
Denken abnehmen.
Nur der Mensch kann entscheiden, wie auf eine 
Wertebereichsüberschreitung zu reagieren ist und dann den dafür 
richtigen Code hinschreiben.
Er muß auch nicht mit der Holzhammermethode draufhauen und nach jedem 
Minischritt ein riesen Bollwerk an Tests durchlaufen lassen, sondern 
macht den Test nur an den signifikanten Stellen.

In einer Hardwaresteuerung ist eine Begrenzung auf 0..359 oft sogar 
Unsinn, da die DACs, ADCs, Schrittmotoren, Positionsgeber usw. mit 
anderen Auflösungen arbeiten, d.h. die Nutzereingaben eh umgerechnet 
werden müssen. Z.B. für einen 10Bit-DAC auf 0..1023.

Bitfelder hat man gerne genommen, als der RAM noch knapp war (AT89C51: 
128 Byte).
Nachdem ich aber gesehen habe, was für ein riesen Wust an Code 
(Schieben, Maskieren) da entsteht, runde ich immer auf den nächsten 
Standardtyp auf und freue mich über den kleinen und schnellen Code.

Mariella M. schrieb:
> In Ada können solche Arrays wie oben definiert im Weiteren
> ganz normal verwendet werden - mit Zugriff auf jeden beliebigen Index.

Damit versteckt er aber nur den Wust an nötigen Manipulationen, der 
erzeugte Code bleibt trotzdem groß und langsam.

: Bearbeitet durch User
Autor: Vincent H. (vinci)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dynamo schrieb:
> Wenn es im Embedded Bereich eine Alternative zu C geben würde, die
> dieselbe Kontrolle über die Hardware und dieselben
> Optimierungsmöglichkeiten bei gleichem Footprint ohne die Probleme geben
> würde, wäre diese Sprache (nennen wir sie mal hypothetisch "D+++") schon
> längst State of the Art.

C++, Rust?
Es is ja nicht so als obs keine besseren Tools gäbe. Verwenden tut sie 
halt kaum wer.

Autor: Oliver S. (oliverso)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Vincent H. schrieb:
> C++, Rust?
> Es is ja nicht so als obs keine besseren Tools gäbe. Verwenden tut sie
> halt kaum wer.

Doch, überall da, wo es C nicht braucht. Und das ist ausserhalb der 
Embedded-Welt so ziemlich eine ganze Menge (ausser dem Linux-Kern...)

Oliver

Autor: Vincent H. (vinci)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oliver S. schrieb:
> Vincent H. schrieb:
>> C++, Rust?
>> Es is ja nicht so als obs keine besseren Tools gäbe. Verwenden tut sie
>> halt kaum wer.
>
> Doch, überall da, wo es C nicht braucht. Und das ist ausserhalb der
> Embedded-Welt so ziemlich eine ganze Menge (ausser dem Linux-Kern...)
>
> Oliver

Ja nona, ich hab natürlich die (nicht ganz so kleine) embedded Welt 
gemeint ;)

Autor: Jemand (Gast)
Datum:

Bewertung
3 lesenswert
nicht lesenswert
Peter D. schrieb:
> Damit versteckt er aber nur den Wust an nötigen Manipulationen,

Hold the presses, das Feature tut was es soll!!1

> der erzeugte Code bleibt trotzdem groß und langsam.

Der Code, der das Array nutzt, muss sich nicht mit dessen internen 
Abbildung rumschlagen, die Entscheidung wie es im Speicher liegt kann 
mit einer einzigen Zeile geändert werden.

Im übrigen ist RAM auf modernen (nicht-μC) Systemen oft relativ langsam, 
Zugriff auf gepackte Daten können wegen des Cachevorteils schneller 
sein.

Autor: ~Mercedes~  . (lolita)
Datum:

Bewertung
-3 lesenswert
nicht lesenswert
Geiles Thema! ;-P

@Mariella,

Wo hast Du den obrigen Artilel her?
Kannst Du mal ne Quelle angeben?
Klar kann man in C und C++ schön und
einfach mit Bitfeldern arbeiten, man
muß sich die fehlenden Funktionen nur
mittels Makro oder Inline Funktion
selbst schaffen.
Dann ists genau so einfach wie in Pascal.

Arbeitest Du mit Ada oder Pascal?

mfg

Autor: Derwoichbin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vincent H. schrieb:
>C++, Rust?
>Es is ja nicht so als obs keine besseren Tools gäbe. Verwenden tut sie
>halt kaum wer.


Ich persönlich behalte ja https://ziglang.org im Auge. Vielleicht ist 
das in ein paar Jahren eine Alternative.

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gemäß den Nutzungsbedingungen

  https://www.mikrocontroller.net/user/conditions

ist das Posten unter verschiedenen Identitäten innerhalb eines Threads 
nicht erlaubt. Ich bitte, das einzuhalten. Sonst muss ich hier Beiträge 
löschen.

Beitrag #5896734 wurde von einem Moderator gelöscht.
Dieser Beitrag kann nur von angemeldeten Benutzern beantwortet werden. Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail, Yahoo oder Facebook? Keine Anmeldung erforderlich!
Mit Google-Account einloggen | Mit Facebook-Account einloggen
Noch kein Account? Hier anmelden.