1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/Makefile Wed Oct 30 02:44:44 2024 +0100
1.3 @@ -0,0 +1,28 @@
1.4 +CXX ?= g++
1.5 +CXXFLAGS ?= -O2 -g3 -ggdb -Wall -Wno-sign-compare
1.6 +CXXFLAGS += --std=c++20
1.7 +CXXFLAGS += -fsanitize=undefined -fsanitize=address
1.8 +LDFLAGS ?=
1.9 +
1.10 +SRC = $(shell find -maxdepth 1 -name '*.cpp')
1.11 +BIN = $(shell find -maxdepth 1 -name '*.cpp' | xargs basename -s .cpp)
1.12 +
1.13 +all: $(BIN)
1.14 +
1.15 +.PHONY: all run clean
1.16 +
1.17 +clean:
1.18 + $(RM) $(BIN)
1.19 +
1.20 +run: $(BIN)
1.21 + @echo "\e[1;32mHappy path without exceptions:\e[0m"
1.22 + @for bin in $(BIN); do ./$$bin ; done
1.23 + @echo; echo
1.24 + @echo "\e[1;32mInterrupted by exceptions:\e[0m"
1.25 + @for bin in $(BIN); do ./$$bin fail; done
1.26 +
1.27 +$(BIN): $(SRC)
1.28 + $(CXX) $(CXXFLAGS) -o $(@) $(@).cpp $(LDFLAGS)
1.29 +
1.30 +# Blok finally při odchytávání výjimek: C++ vs. Java
1.31 +# https://blog.frantovo.cz/c/395/
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/bad.cpp Wed Oct 30 02:44:44 2024 +0100
2.3 @@ -0,0 +1,26 @@
2.4 +#include <iostream>
2.5 +#include <exception>
2.6 +
2.7 +void fxThrowing(bool fail, void* data) {
2.8 + std::cout << " doing something with data " << data << std::endl;
2.9 + if (fail) throw std::logic_error("error from fxThrowing()");
2.10 +}
2.11 +
2.12 +void fxAllocating(bool fail) {
2.13 + void* data = malloc(486);
2.14 + std::cout << " allocated memory at: " << data << std::endl;
2.15 + fxThrowing(fail, data);
2.16 + free(data);
2.17 + std::cout << " freed memory at: " << data << std::endl;
2.18 +}
2.19 +
2.20 +int main(int argc, char** argv) {
2.21 + bool fail = argc == 2 && std::string("fail") == argv[1];
2.22 + const char* name = "bad";
2.23 + std::cout << name << " (fail=" << fail << ")\n";
2.24 + try {
2.25 + fxAllocating(fail);
2.26 + } catch (const std::exception& e) {
2.27 + std::cout << " caught exception: " << e.what() << std::endl;
2.28 + }
2.29 +}
2.30 \ No newline at end of file
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/good-class-generic.cpp Wed Oct 30 02:44:44 2024 +0100
3.3 @@ -0,0 +1,42 @@
3.4 +#include <iostream>
3.5 +#include <exception>
3.6 +
3.7 +template<typename T>
3.8 +class Resource {
3.9 +private:
3.10 + Resource(const Resource&) = delete;
3.11 + Resource& operator=(const Resource&) = delete;
3.12 +public:
3.13 + T* data;
3.14 + void(*dtor)(T*);
3.15 +
3.16 + Resource(T* data, void(*dtor)(T*)) : data(data), dtor(dtor) {
3.17 + std::cout << " created resource for data at: " << data << std::endl;
3.18 + }
3.19 +
3.20 + virtual ~Resource() {
3.21 + dtor(data);
3.22 + std::cout << " called destructor on: " << data << std::endl;
3.23 + }
3.24 +};
3.25 +
3.26 +void fxThrowing(bool fail, void* data) {
3.27 + std::cout << " doing something with data " << data << std::endl;
3.28 + if (fail) throw std::logic_error("error from fxThrowing()");
3.29 +}
3.30 +
3.31 +void fxAllocating(bool fail) {
3.32 + Resource buf(malloc(486), free);
3.33 + fxThrowing(fail, buf.data);
3.34 +}
3.35 +
3.36 +int main(int argc, char** argv) {
3.37 + bool fail = argc == 2 && std::string("fail") == argv[1];
3.38 + const char* name = "good-class-generic";
3.39 + std::cout << name << " (fail=" << fail << ")\n";
3.40 + try {
3.41 + fxAllocating(fail);
3.42 + } catch (const std::exception& e) {
3.43 + std::cout << " caught exception: " << e.what() << std::endl;
3.44 + }
3.45 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/good-class.cpp Wed Oct 30 02:44:44 2024 +0100
4.3 @@ -0,0 +1,41 @@
4.4 +#include <iostream>
4.5 +#include <exception>
4.6 +
4.7 +class Buffer {
4.8 +private:
4.9 + Buffer(const Buffer&) = delete;
4.10 + Buffer& operator=(const Buffer&) = delete;
4.11 +public:
4.12 + size_t size;
4.13 + void* data;
4.14 +
4.15 + Buffer(size_t size) : size(size), data(malloc(size)) {
4.16 + std::cout << " allocated memory at: " << data << std::endl;
4.17 + }
4.18 +
4.19 + virtual ~Buffer() {
4.20 + free(data);
4.21 + std::cout << " freed memory at: " << data << std::endl;
4.22 + }
4.23 +};
4.24 +
4.25 +void fxThrowing(bool fail, void* data) {
4.26 + std::cout << " doing something with data " << data << std::endl;
4.27 + if (fail) throw std::logic_error("error from fxThrowing()");
4.28 +}
4.29 +
4.30 +void fxAllocating(bool fail) {
4.31 + Buffer buf(486);
4.32 + fxThrowing(fail, buf.data);
4.33 +}
4.34 +
4.35 +int main(int argc, char** argv) {
4.36 + bool fail = argc == 2 && std::string("fail") == argv[1];
4.37 + const char* name = "good-class";
4.38 + std::cout << name << " (fail=" << fail << ")\n";
4.39 + try {
4.40 + fxAllocating(fail);
4.41 + } catch (const std::exception& e) {
4.42 + std::cout << " caught exception: " << e.what() << std::endl;
4.43 + }
4.44 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/good-finally.cpp Wed Oct 30 02:44:44 2024 +0100
5.3 @@ -0,0 +1,36 @@
5.4 +#include <iostream>
5.5 +#include <exception>
5.6 +
5.7 +void fxThrowing(bool fail, void* data) {
5.8 + std::cout << " doing something with data " << data << std::endl;
5.9 + if (fail) throw std::logic_error("error from fxThrowing()");
5.10 +}
5.11 +
5.12 +void fxAllocating(bool fail) {
5.13 + void* data = malloc(486);
5.14 + std::cout << " allocated memory at: " << data << std::endl;
5.15 +
5.16 + std::exception_ptr e;
5.17 + try {
5.18 + fxThrowing(fail, data);
5.19 + } catch (...) {
5.20 + e = std::current_exception();
5.21 + }
5.22 +
5.23 + // finally:
5.24 + free(data);
5.25 + std::cout << " freed memory at: " << data << std::endl;
5.26 +
5.27 + if (e) std::rethrow_exception(e);
5.28 +}
5.29 +
5.30 +int main(int argc, char** argv) {
5.31 + bool fail = argc == 2 && std::string("fail") == argv[1];
5.32 + const char* name = "good-finally";
5.33 + std::cout << name << " (fail=" << fail << ")\n";
5.34 + try {
5.35 + fxAllocating(fail);
5.36 + } catch (const std::exception& e) {
5.37 + std::cout << " caught exception: " << e.what() << std::endl;
5.38 + }
5.39 +}
5.40 \ No newline at end of file
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/good-smart-pointer.cpp Wed Oct 30 02:44:44 2024 +0100
6.3 @@ -0,0 +1,38 @@
6.4 +#include <iostream>
6.5 +#include <exception>
6.6 +#include <memory>
6.7 +
6.8 +/** not needed, just for logging */
6.9 +void* myMalloc(size_t size) {
6.10 + void* ptr = ::malloc(size);
6.11 + std::cout << " allocated memory at: " << ptr << std::endl;
6.12 + return ptr;
6.13 +}
6.14 +
6.15 +/** not needed, just for logging */
6.16 +void myFree(void* ptr) {
6.17 + ::free(ptr);
6.18 + std::cout << " freed memory at: " << ptr << std::endl;
6.19 +}
6.20 +
6.21 +void fxThrowing(bool fail, void* data) {
6.22 + std::cout << " doing something with data " << data << std::endl;
6.23 + if (fail) throw std::logic_error("error from fxThrowing()");
6.24 +}
6.25 +
6.26 +void fxAllocating(bool fail) {
6.27 + // std::shared_ptr<void> buf(malloc(486), free); // standard functions
6.28 + std::shared_ptr<void> buf(myMalloc(486), myFree); // our ones with logging
6.29 + fxThrowing(fail, buf.get());
6.30 +}
6.31 +
6.32 +int main(int argc, char** argv) {
6.33 + bool fail = argc == 2 && std::string("fail") == argv[1];
6.34 + const char* name = "good-smart-pointer";
6.35 + std::cout << name << " (fail=" << fail << ")\n";
6.36 + try {
6.37 + fxAllocating(fail);
6.38 + } catch (const std::exception& e) {
6.39 + std::cout << " caught exception: " << e.what() << std::endl;
6.40 + }
6.41 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/good-vector.cpp Wed Oct 30 02:44:44 2024 +0100
7.3 @@ -0,0 +1,24 @@
7.4 +#include <iostream>
7.5 +#include <exception>
7.6 +#include <vector>
7.7 +
7.8 +void fxThrowing(bool fail, void* data) {
7.9 + std::cout << " doing something with data " << data << std::endl;
7.10 + if (fail) throw std::logic_error("error from fxThrowing()");
7.11 +}
7.12 +
7.13 +void fxAllocating(bool fail) {
7.14 + std::vector<char> buf(486);
7.15 + fxThrowing(fail, buf.data());
7.16 +}
7.17 +
7.18 +int main(int argc, char** argv) {
7.19 + bool fail = argc == 2 && std::string("fail") == argv[1];
7.20 + const char* name = "good-vector";
7.21 + std::cout << name << " (fail=" << fail << ")\n";
7.22 + try {
7.23 + fxAllocating(fail);
7.24 + } catch (const std::exception& e) {
7.25 + std::cout << " caught exception: " << e.what() << std::endl;
7.26 + }
7.27 +}