Skip to content

Commit 13af253

Browse files
committed
error handling
1 parent eab012b commit 13af253

File tree

11 files changed

+740
-0
lines changed

11 files changed

+740
-0
lines changed

c++/06_error_handling/00_errno.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include <cmath>
2+
#include <iostream>
3+
4+
int main() {
5+
double d = std::sqrt(4);
6+
std::cout << d << " " << errno << std::endl;
7+
8+
d = std::sqrt(-4);
9+
std::cout << d << " " << errno << std::endl;
10+
11+
d = 0;
12+
13+
errno = 0;
14+
15+
return 0;
16+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include <cmath>
2+
#include <iostream>
3+
4+
// implment a square root function that "deals with" negative
5+
// numbers. Moreover according to the logic of the program, d should
6+
// never be greater than 50
7+
double square_root(const double d);
8+
9+
struct Negative_number {};
10+
11+
struct Bigger_than_expected {};
12+
13+
int main() {
14+
try {
15+
std::cout << "please insert a number\n";
16+
double number;
17+
std::cin >> number;
18+
auto d = square_root(number);
19+
std::cout << "square root of " << number << " is " << d << '\n';
20+
return 0;
21+
} catch (const Negative_number) {
22+
std::cerr << "The square root of a negative number is a complex number.\n"
23+
"square_root() is "
24+
<< "limited to handle positive double numbers.\n";
25+
return 1;
26+
} catch (const Bigger_than_expected) {
27+
std::cerr << "The function square_root has been called with a parameter "
28+
"greater than 50.\n"
29+
<< "This means there is a bug in the algorithm that generated "
30+
"this number.\n";
31+
return 2;
32+
} catch (...) {
33+
std::cerr << "Unknown exception. Aborting.\n";
34+
return 3;
35+
}
36+
}
37+
38+
double square_root(const double d) {
39+
// test the pre-conditions
40+
if (d < 0)
41+
throw Negative_number{};
42+
if (d > 50)
43+
throw Bigger_than_expected{};
44+
return std::sqrt(d);
45+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#include <cmath>
2+
#include <iostream>
3+
#include <string>
4+
#include <utility>
5+
6+
// implment a square root function that "deals with" negative
7+
// numbers. Moreover according to the logic of the program, d should
8+
// never be greater than 50
9+
double square_root(const double d);
10+
11+
struct Square_root_invalid {
12+
std::string message;
13+
Square_root_invalid(std::string s) : message{std::move(s)} {}
14+
};
15+
16+
int main() {
17+
try {
18+
std::cout << "please insert a number\n";
19+
double number;
20+
std::cin >> number;
21+
auto d = square_root(number);
22+
std::cout << "square root of " << number << " is " << d << '\n';
23+
return 0;
24+
} catch (const Square_root_invalid& s) {
25+
std::cerr << s.message << std::endl;
26+
return 1;
27+
} catch (...) {
28+
std::cerr << "Unknown exception. Aborting.\n";
29+
return 3;
30+
}
31+
}
32+
33+
double square_root(const double d) {
34+
// test the pre-conditions
35+
if (d < 0)
36+
throw Square_root_invalid{"Cannot handle negative numbers. You gave me " +
37+
std::to_string(d)};
38+
if (d > 50)
39+
throw Square_root_invalid{
40+
"The argument of square_root must be lower than 50. You gave me " +
41+
std::to_string(d)};
42+
return sqrt(d);
43+
}

c++/06_error_handling/03_error.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include <cmath>
2+
#include <iostream>
3+
4+
#include "ap_error.hpp"
5+
6+
// implment a square root function that "deals with" negative
7+
// numbers. Moreover according to the logic of the program, d should
8+
// never be greater than 50
9+
double square_root(const double d);
10+
11+
struct Square_root_invalid {
12+
std::string message;
13+
Square_root_invalid(std::string s) : message{std::move(s)} {}
14+
const char* what() const { return message.c_str(); }
15+
};
16+
17+
int main() {
18+
try {
19+
std::cout << "please insert a number\n";
20+
double number;
21+
std::cin >> number;
22+
double d = square_root(number);
23+
std::cout << "square root of " << number << " is " << d << '\n';
24+
return 0;
25+
} catch (const Square_root_invalid& e) {
26+
std::cerr << e.what() << std::endl;
27+
return 2;
28+
} catch (const std::exception& e) {
29+
std::cerr << e.what() << std::endl;
30+
return 1;
31+
} catch (...) {
32+
std::cerr << "Unknown exception. Aborting.\n";
33+
return 3;
34+
}
35+
}
36+
37+
double square_root(const double d) {
38+
// test the pre-conditions
39+
40+
AP_ERROR(d >= 0 && d <= 50, Square_root_invalid)
41+
<< "In our library the argument must be positive and less or equal than "
42+
"50.\n\nYou passed "
43+
<< d << ".\n";
44+
45+
// AP_ERROR(d >= 0 && d <= 50) << "In our library the argument must be
46+
// positive "
47+
// "and less or equal than 50.\n";
48+
49+
// AP_ERROR_GE(d, 0) << "Cannot handle negative numbers.\n";
50+
51+
// AP_ERROR_LE(d, 50) << "According to the implemented algorithm, the argument
52+
// "
53+
// "must be less than 50.\n";
54+
55+
// AP_ERROR_IN_RANGE(d,0,50);
56+
57+
return sqrt(d);
58+
}

c++/06_error_handling/04_assert.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include <cassert>
2+
#include <cmath>
3+
#include <iostream>
4+
5+
#include "ap_error.hpp"
6+
7+
// implment a square root function that "deals with" negative
8+
// numbers. Moreover according to the logic of the program, d should
9+
// never be greater than 50
10+
double square_root(const double d);
11+
12+
int main() {
13+
try {
14+
std::cout << "please insert a number\n";
15+
double number;
16+
std::cin >> number;
17+
double d = square_root(number);
18+
std::cout << "square root of " << number << " is " << d << '\n';
19+
return 0;
20+
} catch (const std::exception& e) {
21+
std::cerr << e.what() << '\n';
22+
return 1;
23+
} catch (...) {
24+
std::cerr << "Unknown exception. Aborting.\n";
25+
return 3;
26+
}
27+
}
28+
29+
double square_root(const double d) {
30+
// test the pre-conditions
31+
// assert(d >= 0 && d <= 50); // provided by C, no execeptions
32+
33+
AP_ASSERT(d >= 0 && d <= 50) << "d should be in the range [0,50]";
34+
35+
// AP_ASSERT_IN_RANGE(d,0,50);
36+
return sqrt(d);
37+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#include <iostream>
2+
#include <vector>
3+
4+
#include "ap_error.hpp"
5+
6+
class Foo {
7+
public:
8+
Foo() { std::cout << "Foo" << std::endl; }
9+
~Foo() { std::cout << "~Foo" << std::endl; }
10+
};
11+
12+
class Bar {
13+
public:
14+
Bar() { std::cout << "Bar" << std::endl; }
15+
~Bar() { std::cout << "~Bar" << std::endl; }
16+
};
17+
18+
class Vector {
19+
double* elem;
20+
21+
public:
22+
Vector(const unsigned int l) : elem{new double[l]} {
23+
std::cout << "Vector" << std::endl;
24+
}
25+
~Vector() {
26+
delete[] elem;
27+
std::cout << "~Vector" << std::endl;
28+
}
29+
};
30+
31+
class ManyResources {
32+
double* ptr;
33+
Vector v;
34+
35+
public:
36+
ManyResources() : ptr{nullptr}, v{3} {
37+
std::cout << "Manyresources" << std::endl;
38+
try {
39+
ptr = new double[5]; // new(std::nothrow) double[5] could be better
40+
AP_ERROR(false) << "Error in ManyResources ctor." << std::endl;
41+
} catch (...) {
42+
delete[] ptr; // <----
43+
throw; // re-throw
44+
}
45+
}
46+
47+
~ManyResources() {
48+
std::cout << "~Manyresources" << std::endl;
49+
delete[] ptr; // <----
50+
}
51+
};
52+
53+
int main() {
54+
Foo f;
55+
int* raw_ptr = new int[7]; // do not use raw ptr
56+
try {
57+
// int * raw_ptr=new int[7]; // wrong because raw_ptr would not be visible
58+
// inside the catch-clause
59+
ManyResources mr;
60+
Bar b;
61+
62+
} catch (const std::exception& e) {
63+
std::cerr << e.what() << std::endl;
64+
65+
delete[] raw_ptr; // <--- try to comment this and run valgrind or use the
66+
// sanitize library
67+
return 1;
68+
69+
} catch (...) {
70+
std::cerr << "Unknown exception. Aborting.\n" << std::endl;
71+
72+
delete[] raw_ptr; // <---
73+
return 2;
74+
}
75+
76+
delete[] raw_ptr; // <---
77+
return 0;
78+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include <iostream>
2+
#include <memory>
3+
4+
#include "ap_error.hpp"
5+
6+
class Vector {
7+
std::unique_ptr<double[]> elem;
8+
9+
public:
10+
Vector(const unsigned int l) : elem{new double[l]} {}
11+
12+
Vector(Vector&&) noexcept = default;
13+
Vector& operator=(Vector&&) noexcept = default;
14+
15+
double& operator[](const unsigned int i) noexcept { return elem[i]; }
16+
17+
const double& operator[](const unsigned int i) const noexcept {
18+
return elem[i];
19+
}
20+
21+
~Vector() noexcept { std::cout << "~Vector\n"; }
22+
};
23+
24+
class ManyResources {
25+
std::unique_ptr<double[]> ptr;
26+
Vector v;
27+
28+
public:
29+
ManyResources() : ptr{new double[5]}, v{3} {
30+
std::cout << "ManyResources ctor\n";
31+
AP_ERROR(false) << "I am simulating something wrong.\n";
32+
}
33+
~ManyResources() noexcept { std::cout << "~ManyResources\n"; }
34+
};
35+
36+
int main() {
37+
try {
38+
std::unique_ptr<int[]> up{new int[7]}; // RAII
39+
ManyResources mr;
40+
41+
} catch (const std::exception& e) {
42+
std::cerr << e.what() << std::endl;
43+
return 1;
44+
45+
} catch (...) {
46+
std::cerr << "Unknown exception. Aborting.\n" << std::endl;
47+
return 2;
48+
}
49+
50+
return 0;
51+
}

c++/06_error_handling/Makefile

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
SRC = 00_errno.cpp \
2+
01_exceptions.cpp \
3+
02_exceptions.cpp \
4+
03_error.cpp \
5+
04_assert.cpp \
6+
05_stack_unwinding.cpp \
7+
06_smart_pointers.cpp
8+
9+
CXX = c++
10+
CXXFLAGS = -Wall -Wextra -g -std=c++11
11+
12+
EXE = $(SRC:.cpp=.x)
13+
14+
# eliminate default suffixes
15+
.SUFFIXES:
16+
SUFFIXES =
17+
18+
# just consider our own suffixes
19+
.SUFFIXES: .cpp .x
20+
21+
all: $(EXE)
22+
23+
.PHONY: all
24+
25+
%.x: %.cpp
26+
$(CXX) $< -o $@ $(CXXFLAGS)
27+
28+
format: $(SRC)
29+
@clang-format -i $^ -verbose || echo "Please install clang-format to run this command"
30+
31+
.PHONY: format
32+
33+
clean:
34+
rm -f $(EXE) *~
35+
36+
.PHONY: clean
37+
38+
03_error.x: ap_error.hpp
39+
04_assert.x: ap_error.hpp
40+
05_stack_unwinding.x: ap_error.hpp
41+
06_smart_pointers.x: ap_error.hpp
42+
43+
format: ap_error.hpp

0 commit comments

Comments
 (0)