Hallo zusammen,
generell ist es verpönt, Werte und Status-Daten in einer Variable
miteinander zu mischen. Für meinen aktuellen Anwendungsfall ist aber
alles andere noch schlimmer, also Augen zu und durch. Außerdem ist es
bei den Fließkommazahlen mit NaNs auch üblich.
Banal ist es jetzt einfach so, dass INT_MIN aus dem Pool der gültigen
Werte entfernt wurde und ungültige Daten markiert.
Eine der einfachsten denkbaren Operation wäre dann die sättigende
Multiplikation mit signalisierendem magischen Wert.
1
/** Saettingende warnende Multiplikation (32 Bit)
2
*
3
* Ist einer der Multiplikanten INT32_MIN, ist das Ergebnis auch INT32_MIN.
4
* Ansonsten wird auf den Wertebereich -INT32MAX ... INT32_MAX gesaettigt.
Ich bin mir ziemlich sicher, dass ich nicht der erste bin, der sich
soetwas ausdenkt. Also hat das Vorgehen wohl einen Namen. Kennt jemand
einen recherchierbaren Namen für ein solches Vorgehen?
(Ich hätte auf etwas wie "signaling value" oder so getippt, aber das
scheint ein Begriff aus der Soziologie zu sein.)
So etwas war früher ganz normal.
Schau dir z.B. das getc(FILE*) an. Statt einer char liefert es eine int,
die alle alten 8bit Zeichen und zusätzlich EOF enthalten kann.
Damals hatte halt jeder ganz pragmatisch irgend etwas genommen, was ihm
in diesem Augenblick am einfachsten erschien. Erst später, als Sprachen
wie Rust diesen chaotischen Wildwuchs aufräumten, suchten die Entwickler
Namen für ihre Strategie.
Walter T. schrieb:> Ich bin mir ziemlich sicher, dass ich nicht der erste bin, der sich> soetwas ausdenkt
Aber vielleicht der erste, der dafür eine Multiplikation braucht. Wer
nicht unendliche Rechenleistung zur Verfügung hat wird Bitoperationen
benutzen.
Georg
Der Opa aus der Muppet Show schrieb:> Erst später, [...] suchten die Entwickler Namen für ihre Strategie.
Ja, genau. Wir haben heutzutage später. Zu einem Konzept einen Namen zu
kennen erlaubt einem den Zugang zu einem großen Schatz an Wissen und
Fehlern, die man nicht mehr alle selbst machen muss und zu verwandten
Konzepten.
Georg schrieb:> Aber vielleicht der erste, der dafür eine Multiplikation braucht.
Ich glaube nicht, dass ich darauf ein Patent anmelden können würde.
Wo bleibt die C++-Fraktion mit einem Satz wie "Jaaa, das ist die
eiblisitc*)-class, bei der alle Operatoren überladen sind und die ab
C++25 zum Standardumfang gehören wird!!! Hier <LINK> gibt es eine tolle
Diskussion dazu!"
*) Steht für "every integer behaves like it should in this context"
Michael D. schrieb:> wie wäre es mit https://en.wikipedia.org/wiki/Saturation_arithmetic
Das ist die eine Hälfte. Ob jetzt die builtins für sättigende Arithmetic
besser sind als breiter rechnen und dann klemmen habe ich noch nicht
getestet, weil die ganze Geschichte in einem nicht-zeitkritischen
Code-Teil liegt. Die Builtins sind schon schnell, aber das Vorzeichen
muss dann wieder separat erzeugt werden. Ohne Benchmarks ist das
wahrscheinlich nicht zu entscheiden, was besser geht.
Die andere Hälfte ist die Fehlersignalisierung mittels magischem Wert
(hier: INT_MIN, der sich angeboten hat).
Nachtrag:
Oliver S. schrieb:> https://en.wikipedia.org/wiki/Nullable_type
Das ist wohl die zweite Hälfte. Also habe ich wohl einen "nullable
saturating integer". Oder "saturating nullable integer"? Aber das klingt
vielversprechend. Oder eine "saturating operation on nullable Integer".
Jetzt kann ich meinen Teil der Literaturarbeit weitermachen.
Danke für die brauchbaren Stichwörter!
Walter T. schrieb:> (Ich hätte auf etwas wie "signaling value" oder so getippt, aber das> scheint ein Begriff aus der Soziologie zu sein.)
Mit "sentinel value" oder "Wächterwert" kommt man weiter.
Eine übliche Namenskonvention für Funktionen in C, die Wächterwerte
berücksichtigen, habe ich noch nicht gefunden.
In meinen Augen ist das Hackercoding der übelsten Sorte. Sowas sollte
man sich nicht als Beispiel nehmen.
NaN bedeutet oft ein Speicherfehler (Pointer zeigt in den Wald). Da
Speicherfehler immer kritisch sind, sollte NaN nicht absichtlich
verwendet werden.
Will man einen Fehlerstatus kennzeichnen, nimmt man dafür eine Variable.
Man kann aber auch ein Struct returnieren, was aus Rückgabewert und
Status besteht.
Peter D. schrieb:> NaN bedeutet oft ein Speicherfehler
Da sind wir wohl in verschiedenen Welten. In meiner anderen Welt
bedeutet "NaN" zu 99% "Variable kann nicht in double konvertiert werden"
oder "Gleichungssystem kann aufgrund der Konditionszahl nicht gelöst
werden" - sprich: Inf, -Inf, NaN und -NaN sind Werte, die in einem
fehlerfreien Programm vorkommen können. Aber das ist nicht C und auch
nicht µC.
Peter D. schrieb:> der übelsten Sorte.
Ich bin darüber auch nicht maximal glücklich, aber die anderen Lösungen
sind m.E. schlimmer. Eine zweite Variable mitnehmen oder eine globale
Fehlervariable setzen ist etwas mühsamer threadsicher zu bekommen. (Mein
eigentliches Ziel ist es, Sensordaten aus einer ISR in die Hauptschleife
zu bekommen. Der Fehler ist zu 99,8% timeout wegen nicht angeschlossenem
Sensor und zu 0,2% das ungültige halb empfangene Datentelegramm am
Start.)
Peter D. schrieb:> Will man einen Fehlerstatus kennzeichnen, nimmt man dafür eine Variable.
Ich wäre sehr dankbar für jeden Literaturtipp (auch Quelltext) zum Thema
"sauberere Fehlerbehandlung in C auf dem µC.
So in der Art hätte ich das auch gemacht:
Built-in Function: bool __builtin_mul_overflow (type1 a, type2 b, type3
*res)
Bei allem anderen fängt man sich später nur Probleme ein, weil man an
die Sonderrückgaben nicht mehr denkt. Oder die Architektur den INT_MIN
anders definiert, oder oder oder ....
Dan lieber gleich richtig. Einen Parameter mehr und gut ist es.
Peter D. schrieb:> Will man einen Fehlerstatus kennzeichnen, nimmt man> dafür eine Variable. Man kann aber auch ein Struct> returnieren, was aus Rückgabewert und Status besteht.
Bei Rückgabewerten kein Problem.
Wenn aber größere Mengen solcher Daten irgendwo zu
puffern sind, wird das halt ganz schöne Verschwendung.
Peter D. schrieb:> Will man einen Fehlerstatus kennzeichnen, [...]
Die Implikation habe ich eben überlesen. Ich sehe einen ungültigen Wert
nicht als Fehler, genauwenig wie ich einen leeren String oder das Ende
einer Datei als Fehler sehe.
Wahrscheinlich bin ich deshalb auch gar nicht auf die Idee gekommen, das
als Fehlerbehandlung zu betrachten.
Egon D. schrieb:> .... um WAS zu erreichen?
Um eine Variable weiterzuverarbeiten, ohne dass der Status-Wert verloren
geht.
Walter T. schrieb:> (Mein> eigentliches Ziel ist es, Sensordaten aus einer ISR in die Hauptschleife> zu bekommen. Der Fehler ist zu 99,8% timeout wegen nicht angeschlossenem> Sensor und zu 0,2% das ungültige halb empfangene Datentelegramm am> Start.)
dann übergebe halt nur gültige Werte in deine MAIN....
solange die Sensordaten ungültig sind gibt es keine neuen
Walter T. schrieb:> Ich sehe einen ungültigen Wert nicht als Fehler,> genauwenig wie ich einen leeren String oder das> Ende einer Datei als Fehler sehe.
Diese Fälle sind nicht vergleichbar, sondern aus
mathematischen bzw. logischen Gründen wesensverschieden.
> Egon D. schrieb:>> .... um WAS zu erreichen?>> Um eine Variable weiterzuverarbeiten, ohne dass der> Status-Wert verloren geht.
Der Status-Wert "ungültig" sagt, dass keine Belegung
vorliegt, die dem Wertebereich der Variablen angehört.
Wie sinnvoll es ist, mit einem Algorithmus Werte zu
verarbeiten, für die der Algorithmus überhaupt nicht
definiert ist, kannst Du Dir vielleicht selbst
überlegen.
Du kommst mir wie ein Schüler vor, der "einfach Unendlich
durch Unendlich teilen" will. Jeder Mathematiker antwortet
darauf, dass Unendlich keine reelle Zahl ist, durch die
man so einfach teilen darf.
Ulrich schrieb:> dann übergebe halt nur gültige Werte in deine MAIN....> solange die Sensordaten ungültig sind gibt es keine neuen
Ungünstig, wenn der folgende Algorithmus von gleichmäßiger
Abtastung ausgeht...
Immer Wert und Zeitstempel abzuspeichern vergrößert den
Speicherbedarf beträchtlich.
Ulrich schrieb:> dann übergebe halt nur gültige Werte in deine MAIN....> solange die Sensordaten ungültig sind gibt es keine neuen
Ist das (inkl. Quelltext) als Scherz oder sokratisches Argument gemeint?
Es ist komplizierter. Es muss eine Extra-Initialisierung für Start bei
ungültigem Wert vorgesehen werden. Die main()-Funktion merkt gar nicht,
wenn der "aktuell gültige" Wert schon uralt ist. Das sieht auf den
ersten Blick eher wie ein Antipattern aus.
1
int32_tvalue=INT_MIN;
2
int32_tlastValid=INT_MIN;
3
constint32_tscaling=25400;
4
constint32_toffset=30;
5
6
ISR()
7
{
8
int32_ttemp;
9
boolisValid=getSensor(&temp);
10
if(isValid)
11
{
12
value=temp;
13
lastValid=temp;
14
}
15
else
16
{
17
value=INT32_MIN;
18
}
19
}
20
main()
21
{
22
while(1)
23
{
24
int32_tlen=satmulwarn_s32(value,scaling);
25
len=sataddwarn_s32(len,offset);
26
if(len!=INT32_MIN)display(len);
27
elsedisplay("error");
28
29
doWhatYouWantWith(lastValid);
30
}
31
}
Das ist einfacher, lockfrei, main() weiß, ob die gültigen Daten aktuell
sind, es gibt keine Initialisierungsprobleme. Ich darf nur nicht auf die
dumme Idee kommen, aus "lastValid" auf irgendeine Eigenschaft von
"valid" schließen zu wollen.
Nicht gegen Mutexe in Kontexten, wo ein solches Konstrukt wirklich nötig
ist. Aber hier?
Egon D. schrieb:> Wie sinnvoll es ist, mit einem Algorithmus Werte zu> verarbeiten, für die der Algorithmus überhaupt nicht> definiert ist, kannst Du Dir vielleicht selbst> überlegen.
Warum sollte man einen Algorithmus so designen, dass er mit
vorhersehbaren Werten nicht klarkommt?
Walter T. schrieb:> Nicht gegen Mutexe in Kontexten, wo ein solches Konstrukt wirklich nötig> ist. Aber hier?
was ist denn dein Ziel system?
falls es ein 8bit Microcontroller ist (was dieses Forum nahelegt)
ist dein code buggy
Ulrich schrieb:> falls es ein 8bit Microcontroller ist (was dieses Forum nahelegt)> ist dein code buggy
Es ist natürlich ein 32Bitter, sonst wäre der Code buggy.
Egon D. schrieb:> Jeder Mathematiker antwortet> darauf, dass Unendlich keine reelle Zahl ist, durch die> man so einfach teilen darf.
Und jeder Numeriker wird Dir sagen, dass "unendlich" ein Wert ist, mit
dem Dein Programm gefälligst klarzukommen hat.
Walter T. schrieb:> Ulrich schrieb:>> falls es ein 8bit Microcontroller ist (was dieses Forum nahelegt)>> ist dein code buggy>> Es ist natürlich ein 32Bitter, sonst wäre der Code buggy.>> Egon D. schrieb:>> Jeder Mathematiker antwortet>> darauf, dass Unendlich keine reelle Zahl ist, durch die>> man so einfach teilen darf.>> Und jeder Numeriker wird Dir sagen, dass "unendlich" ein Wert ist, mit> dem Dein Programm gefälligst klarzukommen hat.
Jeder Psychiater würde euch sagen, dass ihr Nullen seid.
Ulrich schrieb:> Egon D. schrieb:>> Ungünstig, wenn der folgende Algorithmus von>> gleichmäßiger Abtastung ausgeht...>> und wo hat der TO dieses Requirement gestellt?
Nun, der TO hat davon gesprochen, dass es ihm um die
Übergabe von Sensorwerten aus einer ISR an das
Hauptprogramm geht, und eine denkbare Interpretation
dieser Worte ist, dass die ISR am Timer-Interrupt
hängt.
Das war zumindest das Bild, das sich mir aufdrängte.
Ulrich schrieb:> dann übergebe halt nur gültige Werte in deine MAIN....> solange die Sensordaten ungültig sind gibt es keine neuen> ISR()> {> if(data_valid & mutex_free)> {> global_sensor_data = sensor_data;> global_sensor_flag = true;> }> }> main()> {> while(1)> {> if(global_sensor_flag)> {> mutex_free = false;> local_data = global_sensor_data;> global_sensor_flag = false;> mutex_free = true;> }> }> }>
So langsam wird es off-Topic, aber: Fehlt hier nicht eine
Memory-Barrier? (Unter der Annahme, dass die drei globalen Variablen
volatile sind und die Schreib- und Lesereihenfolge nicht vertauscht
werden kann.)
1
ISR()
2
{
3
if(data_valid&mutex_free)
4
{
5
global_sensor_data=sensor_data;
6
/* Wenn global_sensor_data _und_ global_sensor_flag volatile, ist hier
7
keine memory barrier noetig, da ISR nicht unterbrochen wird */
8
global_sensor_flag=true;
9
}
10
}
11
main()
12
{
13
while(1)
14
{
15
if(global_sensor_flag)
16
{
17
mutex_free=false;
18
local_data=global_sensor_data;
19
global_sensor_flag=false;
20
/* Memory Barrier erforderlich? */
21
mutex_free=true;
22
}
23
}
24
}
Ich habe ehrlich gesagt noch nie etwas mit Mutexen programmiert. Bislang
habe ich immer Doppelpufferstrategien bevorzugt.
Walter T. schrieb:> Egon D. schrieb:>> Jeder Mathematiker antwortet darauf, dass Unendlich>> keine reelle Zahl ist, durch die man so einfach teilen>> darf.>> Und jeder Numeriker wird Dir sagen, dass "unendlich"> ein Wert ist, mit dem Dein Programm gefälligst> klarzukommen hat.
Moment.
Erstens macht Deine Entgegnung meine Aussage nicht
falsch.
Zweitens hat Deine Entgegnung nix mit dem konkreten
Problem zu tun, das Du geschildert hast.
Daten im Speicher sind ja erstmal nur Binärvektoren;
deren Interpretation als ganze oder natürliche Zahlen
ist zwar üblich und sinnvoll, aber keineswegs zwingend.
Es ist daher absolut zulässig zu definieren: "Jene
Belegung des Binärvektors signalisiert einen ungültigen
Zahlenwert, und für alle anderen Belegungen wird der
Binärvektor nach der üblichen Vorschrift in eine ganze
Zahl umgewandelt."
Das ist mathematisch völlig sauber.
Unsinnig wird es ab dem Punkt, wo Du die "üblichen"
Arithmetik-Befehle des Computers auf Deine privat
umdefinierten Daten anwendest und hoffst, es käme
automagisch das Richtige heraus. Das mag sich für
einzelne Rechenoperationen noch absichern lassen, aber
für ganze Verarbeitungsalgorithmen ist diese Eigenschaft
erst nachzuweisen, und das wird eine harte Nuss werden.
Kein Digitalfilter, keine FFT, kein kleinste-Quadrate-
Schätzer kommt, wenn der Algorithmus für äquidistante
Werte formuliert wurde, automagisch mit nicht-äquidistanten
klar.
Die trivialisierst eine mathematische Frage zu einer
programmiertechnischen Üblichkeit, die man auch
problemlos ändern könnte.
Soviel erstmal. Muss weg.
Egon D. schrieb:> Die trivialisierst eine mathematische Frage zu einer> programmiertechnischen Üblichkeit, die man auch> problemlos ändern könnte.
WTF? Haben wir wieder Aktionswochen für lange Wörter?
Es geht immer noch primär um die Kodierung eines Nicht-Wertes in
Integer. (Für float muss das nicht diskutiert werden, da schon
standardisiert.)
Wie ich schon eingangs schrieb, ist das verpönt. PeDas Reaktion
enspricht dieser Aussage. Das ist gut - es bedeutet, dass es diese
Vorbehalte wirklich gibt.
Bei niedrigen Funktionen sind Vorbehalte üblicherweise ein vages
Unbehagen oder Ekel. Allerdings sollten Menschen ab einem gewissen
Bildungsstand innerhalb ihres eigenen Fachgebiets soetwas
differenzierter beschreiben können.
(Der letzte Absatz ist kein Angriff auf PeDa. Im Gegenteil schätze ich
sogar, dass der eine genannte Grund bei float sogar sehr konkret ist.)
Für GOTO hat mal ein Dijkstra die wichtigsten Kontra-Argumente
zusammengeschrieben. Der hat ja auch nicht einfach "Du bist ein
Pfuscher! So macht man das nicht!" geschrieben. Er hat sich auch nicht
in lange Wortgebilde aus angrenzenden Fachrichtungen geflüchtet.
Deswegen nahm und nimmt man ihn auch ernst, selbst wenn man nicht jedem
Argument zustimmt.
Niemand erwartet, dass plötzlich alle Programmiersprachen oder Libraries
umgestellt werden.
Aber dafür oder dagegen, ob man ein Pattern in eigenen Programmen
verwendet, sollten gute Gründe existieren.
Gründe dafür habe ich gefunden. Sonst wäre mir dieses "Pattern" nicht
eingefallen. Gründe für die Vorbehalte suche ich noch. Einen kenne ich:
Es ist nicht in der Standard-Library. Aber das float in der heutigen
Form irgendwann auch mal nicht.
Walter T. schrieb:> Egon D. schrieb:>> Die trivialisierst eine mathematische Frage zu>> einer programmiertechnischen Üblichkeit, die man>> auch problemlos ändern könnte.>> WTF? Haben wir wieder Aktionswochen für lange Wörter?
Echt jetzt?
In meinem Text war wohl kein Tippfehler zur Hand -- so
als passender Vorwand, um mich vollzupflaumen?
> Es geht immer noch primär um die Kodierung eines> Nicht-Wertes in Integer.
Lies einfach Deinen Eröffnungsbeitrag.
Um die Kodierungsfrage geht es sechs Zeilen lang; die
restlichen 29 Zeilen geht es um die Weiterverarbeitung
eines solchen Wertes.
> [...]> Bei niedrigen Funktionen sind Vorbehalte üblicherweise> ein vages Unbehagen oder Ekel. Allerdings sollten> Menschen ab einem gewissen Bildungsstand innerhalb ihres> eigenen Fachgebiets soetwas differenzierter beschreiben> können.
Sicher.
Menschen eines gewissen Bildungsstandes sollten auch ihre
Fragen so formulieren können, dass die Antworten, die sie
erhalten, zielführend sind.
Und wenn die ersten Antworten am Thema vorbeizugehen
scheinen (oder es tatsächlich tun), sollten sie höflich
und geduldig auf diese Antworten eingehen und ihre Frage
präzisieren oder umformulieren können.
> Aber dafür oder dagegen, ob man ein Pattern in eigenen> Programmen verwendet, sollten gute Gründe existieren.
Selbstverständlich, das ist ein berechtigter Wunsch.
Deine Fragestellung ist im Prinzip interessant und führt
m.E. weit über Dein ursprüngliches Beispiel (Messwerte
und ISR) hinaus.
Dennoch nervt mich Deine schnippische Art der Diskussions-
führung ganz gewaltig; für mich ist hier Schluss.
Wenn es um Sensordaten geht, sind die 32 Bit vielleicht gar nicht nötig?
Dann könnte man doch davon ein Bit abzweigen für gültig/ungültig.
In C formulieren könnte man das dann als struct mit 2 Bitfeldern (1 bzw.
31 Bit lang) und rechnet dann halt auf dem einen Teil, während man den
anderen Teil als Status setzt.
Damit ist Schreiben und Lesen nach wie vor atomar möglich (auf einem
32-Bit-µC natürlich) und kein Platz verschwendet.
Walter T. schrieb:> Außerdem ist es> bei den Fließkommazahlen mit NaNs auch üblich.>> Banal ist es jetzt einfach so, dass INT_MIN aus dem Pool der gültigen> Werte entfernt wurde und ungültige Daten markiert.
Du kannst seltsame Probleme haben...
Also mal aus meiner Sicht: Integerzahlen kennen zwar den Überlauf, aber
keinerlei NaN. Allenfalls kann man dort ein Min und ein Max definieren
und benutzen, um einen zulässigen Integerwert zu ermitteln.
Bei Fließkommazahlen gibt es NaN, die zumeist bei Rechenoperationen
entstehen, wenn das Rechenergebnis zu groß oder zu klein werden würde.
Das ist das Pendent zum Überlauf bei Integer.
All sowas ist auf zu saloppe Planung der zu schreibenden Firmware
zurückzuführen. Sowas ist mir auch schon passiert, aber man kuriert es
am sinnvollsten an der richtigen Stelle und bastelt nicht nachträglich
mit Gültigkeitsflags herum.
W.S.
W.S. schrieb:> Bei Fließkommazahlen gibt es NaN, die zumeist bei Rechenoperationen> entstehen, wenn das Rechenergebnis zu groß oder zu klein werden würde.> Das ist das Pendent zum Überlauf bei Integer.
Nicht ganz. Bei Rechenoperationen, bei denen der Wertebereich der float
ins Positive oder negative überschritten wird, entsteht Inf bsw. -Inf
("Überlauf"). In Bezug auf "Unterlauf" unterscheiden sich die
Bezeichnungen in der Literatur. In einigen Fällen ist "Unterlauf" der
Bereich, der nicht mehr normalisiert dargestellt werden kann. Dann merkt
der Benutzer erst einmal nur, dass die Auflösung abnimmt. Meist ist aber
"Ergebnis kleiner als eps()" gemeint, und das Ergebnis ist einfach 0.
oder -0. .
Mit Inf und -Inf kann man auch weiterrechnen. Ein paar Operationen
weniger als bei regulären Zahlen sind erlaubt. Wird eine nicht-erlaubte
Operation vorgenommen, entsteht ein NaN oder -NaN (Beispiel: Inf * 0 ->
NaN)
NaN sind gedacht als "Ergebnis lässt sich nicht als float/double
darstellen".
Typischer Anwendungsfall: Eingelesene Daten (z.B. Textstrings) lassen
sich nicht als double interpretieren oder noch häufiger: Werte lassen
sich nicht errechnen. Klassiker: Rangabfall. Dann lassen sich einige
Zeilen des Gleichungssystems lösen, einige nicht. Die ungültigen
Ergebnisse werden mit NaN markiert.
Wenn einige Zeilen ungültig sind, heisst das nicht, dass mit dem Rest
der Lösung nichts angefangen werden kann. Deswegen ziehen die number
cruncher es oft vor, eine Rechnung nicht sofort bei einem auftauchenden
NaN abzubrechen, sondern erst einmal weiterzurechnen und nachher
nachzukorrigieren.
Die beste laienverständliche Erklärung dazu habe ich in der
Autobiographie Richard Feynmans gelesen. Seine Mitarbeiter haben damals
in Los Alamos die Verfahren entwickelt, wie man mit falschen
Zwischenergebnissen zu einem korrekten Endergebnis kommt.
Sprich: Bei der Entwicklung der IEEE 754 Fließkommazahlen ist sehr
vieles sehr richtig gemacht worden.
Mit meinem laienhaften Umgang mit Integer hat das wenig zu tun. Aber
komplett abwegig ist das auch nicht.
Bislang habe ich bis auf PeDas sinngemäßes "NaNs sind in meiner
Anwendung meist falsch zugeordnete Zeiger" noch kein Argument gelesen.
Es kam jetzt mehrmals die Behauptung "wenn Du das brauchst, ist Deine
Architektur übel" - ein klassischer Zirkelschluss. Wenn ich ein
"nicht-empfohlenes"-Konstrukt nutzen muss, um ein Ziel zu erreichen, ist
die Architektur nicht gut. Warum ist das Konstrukt nicht empfohlen? Weil
es nur für nicht-gute Architektur gebraucht wird.
Zweimal drüber geschlafen ist mir immer noch nicht die Eingebung
gekommen, was das Schlechte an "Nullbaren Integer" sein soll -
unabhängig vom hier angedachten Anwendungsfall.
Walter T. schrieb:> Also hat das Vorgehen wohl einen Namen. Kennt jemand> einen recherchierbaren Namen für ein solches Vorgehen?
Etwa "inband signaling" könnte passen.
Ergibt in der Praxis aber furchtbaren Spaghetti Code der langfristig
schlecht zu warten ist. Man möchte die Fehlerbehandlung oftmals getrennt
abarbeiten,
z.B. C++ hat dafür die Exceptions.