# HG changeset patch # User František Kučera # Date 1730322529 -3600 # Node ID 64777e5b619f8f060b581736bef1e0e3207b4c64 # Parent 4502b1c7346d326460a4bdec1c86ca09c3c1336e class Finally with lambda diff -r 4502b1c7346d -r 64777e5b619f Makefile --- a/Makefile Wed Oct 30 02:51:12 2024 +0100 +++ b/Makefile Wed Oct 30 22:08:49 2024 +0100 @@ -31,10 +31,10 @@ run: $(BIN) @echo "\e[1;32mHappy path without exceptions:\e[0m" - @for bin in $(BIN); do ./$$bin ; done + @for bin in $(BIN); do ./$$bin ; true; done @echo; echo @echo "\e[1;32mInterrupted by exceptions:\e[0m" - @for bin in $(BIN); do ./$$bin fail; done + @for bin in $(BIN); do ./$$bin fail; true; done $(BIN): $(SRC) $(CXX) $(CXXFLAGS) -o $(@) $(@).cpp $(LDFLAGS) diff -r 4502b1c7346d -r 64777e5b619f good-lambda.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/good-lambda.cpp Wed Oct 30 22:08:49 2024 +0100 @@ -0,0 +1,68 @@ +/** + * cpp-finally + * Copyright © 2024 František Kučera (Frantovo.cz, GlobalCode.info) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +class Finally { +private: + Finally(const Finally&) = delete; + Finally& operator=(const Finally&) = delete; +public: + std::function fx; + + Finally(std::function fx) : fx(fx) { + } + + virtual ~Finally() { + fx(); + } +}; + +void fxThrowing(bool fail, void* data) { + std::cout << " doing something with data " << data << std::endl; + if (fail) throw std::logic_error("error from fxThrowing()"); +} + +void fxAllocating(bool fail) { + void* buf = malloc(486); + void* tmp = malloc(123); + std::cout << " allocated memory at: " << buf << std::endl; + std::cout << " allocated memory at: " << tmp << std::endl; + + Finally finally([&]() { + free(buf); + free(tmp); + std::cout << " freed memory at: " << buf << std::endl; + std::cout << " freed memory at: " << tmp << std::endl; + }); + + fxThrowing(fail, buf); + fxThrowing(fail, tmp); +} + +int main(int argc, char** argv) { + bool fail = argc == 2 && std::string("fail") == argv[1]; + const char* name = "good-lambda"; + std::cout << name << " (fail=" << fail << ")\n"; + try { + fxAllocating(fail); + } catch (const std::exception& e) { + std::cout << " caught exception: " << e.what() << std::endl; + } +}