@asdfman: Du hast recht, das war tatsächlich ein ungünstiges Beispiel.
Was aber deine Erweiterung angeht:
(clang 3.5 auf fedora 22)
Clang ist bei mir jetzt aber auch der einzige Compiler, der sich so verhält. Das ist ja gerade das Porblem mit UB. Auch wenn es sich bei noch so vielen Tests so verhält wie erwartet kann man sich nicht darauf verlassen, dass das immer der Fall ist (sofern die Compilerdokumentation nichts anderes sagt).
Wie dem auch sei, ich glaube wir sind uns alle einig, dass das nicht die geeignete Art und Weise ist um Fehleingaben zu melden und daher hier meine Meinung zum eigentlichen Topic:
Ich vermute mal, dass deine Klasse einen mathematischen Vektor darstellen soll und damit ist ein out-of-bounds-access ein ganz klarer Programmierfehler. In den meisten Fällen sollte die Größe sogar zur Compilezeit bekannt sein. Ergo würde ich hier entweder eine Exception werfen oder sogar ganz auf eine reguläre Laufzeitüberprüfung verzichten und lediglich fürs Debuggen ein paar asserts einbauen. Also entweder
oder
Das steht auch im Einklang mit dem Verhalten von Standardcontainern: Ein std::vector::at wirft übrigens auch eine Exception, während std::vector:perator[] aus Performancegründen überhauptnicht auf Fehleingaben testet.
Die ganzen Varianten mit der Rückgabe von bools oder ungültigen Werten sind meiner Meinung nur dann sinnvoll, wenn auch bei korrekter Programmausführung und mit korrekten/erwarteten Eingabedaten damit gerechnet werden muss, dass kein gültiger Wert zurückgeliefert werden kann. Typische Beispiele sind das parsen von strings oder ein Verbindungsaufbau zu einem Ziel im Netzwerk/Internet.
Was aber deine Erweiterung angeht:
Code:
cat main.cpp;clang++ -std=c++11 -O3 main.cpp;echo ==============; ./a.out
#include <iostream>
double test(int id) {
if(id < 0) {
double *a = nullptr;
double c = *a;
return c;
} else {
return 1.0;
}
}
int main() {
double a = test(-1);
std::cout << a << std::endl;
}
==============
0 //<- kein Segfault
Clang ist bei mir jetzt aber auch der einzige Compiler, der sich so verhält. Das ist ja gerade das Porblem mit UB. Auch wenn es sich bei noch so vielen Tests so verhält wie erwartet kann man sich nicht darauf verlassen, dass das immer der Fall ist (sofern die Compilerdokumentation nichts anderes sagt).
Wie dem auch sei, ich glaube wir sind uns alle einig, dass das nicht die geeignete Art und Weise ist um Fehleingaben zu melden und daher hier meine Meinung zum eigentlichen Topic:
Ich vermute mal, dass deine Klasse einen mathematischen Vektor darstellen soll und damit ist ein out-of-bounds-access ein ganz klarer Programmierfehler. In den meisten Fällen sollte die Größe sogar zur Compilezeit bekannt sein. Ergo würde ich hier entweder eine Exception werfen oder sogar ganz auf eine reguläre Laufzeitüberprüfung verzichten und lediglich fürs Debuggen ein paar asserts einbauen. Also entweder
Code:
double Vektor::get(int index) const {
if (index < 0 || index >= mSize) {
throw std::invalid_argument("ERROR: index does not exist.");
}
return mWerte[index]; // Wert zurückgeben
}
Code:
double Vektor::get(int index) const {
assert(index >= 0);
assert(index < mSize);
return mWerte[index]; // Wert zurückgeben
}
Das steht auch im Einklang mit dem Verhalten von Standardcontainern: Ein std::vector::at wirft übrigens auch eine Exception, während std::vector:perator[] aus Performancegründen überhauptnicht auf Fehleingaben testet.
Die ganzen Varianten mit der Rückgabe von bools oder ungültigen Werten sind meiner Meinung nur dann sinnvoll, wenn auch bei korrekter Programmausführung und mit korrekten/erwarteten Eingabedaten damit gerechnet werden muss, dass kein gültiger Wert zurückgeliefert werden kann. Typische Beispiele sind das parsen von strings oder ein Verbindungsaufbau zu einem Ziel im Netzwerk/Internet.
Zuletzt bearbeitet: