I saw this technique. Before executing the critical code, make a copy of all variables / objects. Then we execute the code. If an error occurs, then just restore everything back. In C ++, this can be done conveniently if you write the correct copy constructors.
In pure C, I saw another method. Sly goto series. Somewhere like that.
ПриВыходеИзВарпРежима() { if (!ДобавитьКораблиВКосмос()) { goto space; } if (!УстановитьУНихДефолтныеКоординаты()) { goto coord; } ... if (!ВключитьЩиты()) { goto guard; } if (!ОбнаружитьПротивников()) {goto anemi;} return ok; anemi: ПровестиДиагностикуВторогоУровня(); guard: ПерекалиброватьЩиты(); coord: УбратьДефолтныеКоординаты(); space: УбратьКораблиСКосмоса(); return bad; }
That is, if an error occurs - go on goto to handlers "rollback to normal".
Yes, I see that you do not want to write "reverse steps", but sometimes it is simply impossible without them.