You can do whatever you want, but systemically it is a lot better than doing it manually and anyone experienced with modern C++ will tell you it essentially stops being a problem.
Also you say not preventing memory leaks but your only example is cycles, which is only happens with reference counting, which is only even necessary with multi-threading. Also it implies a data structure that contains a bunch of shared pointers internally that end up referencing each other, which implies a linked list or tree made out of shared pointers, which is essentially a wild mistake huge mistake in the first place. In practice this doesn't really happen.
> You can do whatever you want, but systemically it is a lot better than doing it manually and anyone experienced with modern C++ will tell you it essentially stops being a problem.
Yeah, it's fine, but I think that systematically the Zig approach is a lot better for my needs and preferences.
> In practice this doesn't really happen.
I've only been programming low-level code for 25 years or so, including hard realtime safety-critical software, where a missed deadline or a stack overflow means dead people, so I have some grasp on what can really happen.
There's a clear tradeoff between forgetting to write some code and not noticing when code runs when you may not expect it to. Saying that one is universally better than the other is, at the very least, unsubstantiated.
Destructors are not modern C++. When I learnt C++, circa 1993, we had destructors. Saying, you should just remember to always look up which destructors run sounds as convincing to me as how I must sound to you when I say you should just remember to put a defer statement when you need to free a resource.
In my low-level code I don't want any calls that I can't see as explicit calls in the code (BTW, it's not that I don't use destructors at all - I'm not a fanatic - it's that I try to avoid relying on RAII).
No one said they were and that isn't the point (and you didn't answer the question). When destructors run isn't a mystery it's deterministic and you know resources need to be freed so you know what it is going to do.
Hidden functions aren't a big deal in practice. You have functions calling other functions in C all the time and you have to know what they are doing under the hood, same with data structures and their operators.
Again, that's like me saying "forgetting defer isn't a big deal in practice." You seem to disagree with that and I disagree with your assertion. It's largely a matter of personal preference.
And no, except for some compile-time tests/assertions and a smattering of lambdas, we don't use most of "modern C++" (or almost any of std). Sometimes we need to emit hand-crafted machine code, and sometimes we may need to mess around with stack frames directly (which means we can't use destructors in those cases. We do use destructors a fair bit, but I personally soured on RAII some ten years ago.
Also you say not preventing memory leaks but your only example is cycles, which is only happens with reference counting, which is only even necessary with multi-threading. Also it implies a data structure that contains a bunch of shared pointers internally that end up referencing each other, which implies a linked list or tree made out of shared pointers, which is essentially a wild mistake huge mistake in the first place. In practice this doesn't really happen.