Funktion zur überprüfung von funktionswerten
-
Hallo, ich möchte eine C Funktion erstellen welche überprüft ob eine Funktion einen rückgabewert hat. so hat ja z.B der log einer negativen zahl keinen Rückgabewert oder die Wurzel einer negativen Zahl auch keinen. Ich möchte also Definitionslücken feststellen und beim erstellen einer Wertetabelle für eine beliebige Funktion hier eintragen dass kein funktionswert existiert. Dieses Programm sollte universell nutzbar sein also für jede Funktion und Definitionslücke. Mir fehlt hierfür leider der Ansatz
mfg Cedric
-
@Cedric123 sagte in Funktion zur überprüfung von funktionswerten:
ob eine Funktion einen rückgabewert hat
Sie ist entwerder void oder hat einen oder es ist undefiniertes Verhalten, das man nict testen kann.
-
@Cedric123 sagte in Funktion zur überprüfung von funktionswerten:
Hallo, ich möchte eine C Funktion erstellen welche überprüft ob eine Funktion einen rückgabewert hat. so hat ja z.B der log einer negativen zahl keinen Rückgabewert oder die Wurzel einer negativen Zahl auch keinen. Ich möchte also Definitionslücken feststellen und beim erstellen einer Wertetabelle für eine beliebige Funktion hier eintragen dass kein funktionswert existiert. Dieses Programm sollte universell nutzbar sein also für jede Funktion und Definitionslücke. Mir fehlt hierfür leider der Ansatz
mfg Cedric
wenn was nicht definiert ist, bekommst du 'nan' oder '+/-inf' als ergebnis.
https://stackoverflow.com/questions/4095337/how-to-check-for-inf-and-or-nan-in-a-double-variabledouble null = 0.0; // sonst merkts der compiler double a = log(-1); double b = 1.0 / null; double c = sqrt(-9); cout << a << endl; cout << b << endl; cout << c << endl;
-
Das geht im Allgemeinen nicht, es gibt keine allgemeine Konvention, wie eine Funktion signalisiert, dass das Ergebnis nicht definiert ist. Mir fallen auf Anhieb folgende Möglichkeiten ein:
- ein falsches Ergebnis
- ein spezielles Ergebnis (wie
-1
oderinf
odernan
oder ein Nullpointer oder oder ...) - die Funktion gibt ein
optional
o.ä. zurück - eine Exception
- ein
longjmp
- ein Absturz
- das Programm wird beendet
- ein globaler Fehlerstatus wird gesetzt
- eine Endlosschleife
- die Funktion gibt ein
bool
zurück und das eigentliche Ergebnis by reference,false
steht für undefiniert
Beispiel:
int factorial(int n) { if (n == 0) return 1; else return n * factorial(n-1); }
Ist für
n < 0
nicht definiert und für zu großen
auch nicht. Im ersten Fall gibts eine Endlosrekursion, die wahrscheinlich nach einiger Zeit zum Absturz führt. Im zweiten Fall gibts einfach wegen Integer-Überlauf ein falsches Ergebnis (eigentlich undefiniertes Verhalten.)Das kann man von außen nicht testen.
-
@Cedric123 Du musst schon wissen, wie die Rückgabewerte der Funktion definiert sind.
Gute Funktionen setzten noch die globale Variable
errno
auf einen entsprechenden Wert.
Den kann man auswerten.
-
@DirkB Also dass "gute" Funktionen
errno
setzen finde ich jetzt mal ne ziemlich gewagte Aussage.
-
@hustbaer sagte in Funktion zur überprüfung von funktionswerten:
Also dass "gute" Funktionen errno setzen finde ich jetzt mal ne ziemlich gewagte Aussage.
Zumindest die vom TO genannten
log
undsqrt
(und auch andere) aus der Standardlib machen das.
-
@DirkB Das ist richtig, errno & Co. sind aber globale Variablen und somit nicht threadsafe. Aber vor 50 Jahren gabs auch noch keine Threads, deshalb sind sie auch in der Standardlib. Bei Singlethread also kein Problem über eine globale Variable zu kommunizieren, bei anspruchsvolleren Aufgaben muss man sowieso selbst ran, denn da reicht die Standardlib nicht aus.
-
Nicht unbedingt, zumindestens unter Linux ist es thread-safe (da "thread local storage" dafür benutzt wird), s.a. Is errno thread-safe?
-
@Th69 Quatsch. Du musst hier nicht ahnungslos alles nachplappern was du irgendwo aufgeschnappt hast.
-
Und warum gibt dieser Code unterschiedliche Adressen für
errno
aus: Ideone-Code (gcc 8.3 unter Linux) - wenn es denn deiner Meinung nach eine globale Variable ist?
-
@Wutz sagte in Funktion zur überprüfung von funktionswerten:
@Th69 Quatsch. Du musst hier nicht ahnungslos alles nachplappern was du irgendwo aufgeschnappt hast.
errno ist auf POSIX Sytemen seit Jahrzehnten Threadsafe.
-
@manni66 @Th69 Würd' ich trotzdem nicht nutzen. Der nächste kompiliert den Code für seine Kaffeemaschine die kaffeekochen und milchschäumen (2 Threads) kann aber von TLS noch nie was gehört hat und dann hast Du (bzw. der) den Salat.
-
errno is a preprocessor macro used for error indication. It expands to a static (until C++11) thread-local (since C++11) modifiable lvalue of type int.
https://en.cppreference.com/w/cpp/error/errno
Finde jetzt gerade nichts zu C , aber da wird es nicht anders sein, wenn Threads unterstützt werden.errno is a preprocessor macro (but see note below) that expands to a thread-local (since C11) modifiable lvalue of type int.
-
@Wutz sagte in Funktion zur überprüfung von funktionswerten:
Das ist richtig, errno & Co. sind aber globale Variablen und somit nicht threadsafe.
siehe hier: 'errno is thread-local; setting it in one thread does not affect its value in any other thread.'
https://linux.die.net/man/3/errnoaber globale variablen verwendet der brave coder sowieso nicht.
-
Ihr habt alle keine Ahnung - wie kann eine (globale) Variable threadsafe sein, wenn <thread.h>, TLS,... gemäß C-Sprachstandard C99 und höher nur optional ist? -- Genau! Nie.
Im Übrigen garantiert der Standard nie eine konkrete Implementierung - hier also die Benutzung von errno in Standardlib-Funktionen -, auch das würdet ihr wissen, wenn ihr die Grundidee vom Standard verstanden hättet - nämlich kein Programmierlehrbuch zu sein, sondern eine Handlungsrichtlinie für Compilerbauer, und dabei eben nicht konkrete Implementierungen vorzuschreiben sondern möglichst viele Freiheiten zu lassen.
Das Aufschnappen und Nachplappern von Pauschalaussagen und Weisheiten aus dem Netz entledigt nicht vom eigenen Nachdenken.
-
-
@Wutz: Wir reden hier aber von konkreten Implementierungen, nicht vom Sprachstandard per se. Also halt du dich daraus!
-
Wir reden hier nicht von konkreten Implementierungen, weil wir von Pauschalaussagen "errno ist threadsafe" reden.
Wer lesen kann ist klar im Vorteil.
-
@Wutz sagte in Funktion zur überprüfung von funktionswerten:
Ihr habt alle keine Ahnung - wie kann eine (globale) Variable threadsafe sein, wenn <thread.h>, TLS,... gemäß C-Sprachstandard C99 und höher nur optional ist? -- Genau! Nie.
errno ist nicht für die interprozess-kommunikation geeignet. solange dein programm nur in einem einzigen thread läuft, funktioniert errno. ein multithreading-errno, wenn es denn einer braucht, muss er sich schon selber programmieren. libraries die atomic integers anbieten gibt es ja.
-
@Bushmaster sagte in Funktion zur überprüfung von funktionswerten:
@Wutz sagte in Funktion zur überprüfung von funktionswerten:
Ihr habt alle keine Ahnung - wie kann eine (globale) Variable threadsafe sein, wenn <thread.h>, TLS,... gemäß C-Sprachstandard C99 und höher nur optional ist? -- Genau! Nie.
errno ist nicht für die interprozess-kommunikation geeignet. solange dein programm nur in einem einzigen thread läuft, funktioniert errno. ein multithreading-errno, wenn es denn einer braucht, muss er sich schon selber programmieren. libraries die atomic integers anbieten gibt es ja.
Das ist falsch. Errno ist nicht für die Interprzesskommunikation gedacht. errno ist in jeweils einem Thread gültig.