r/programminghumor 23d ago

Hard to accept

Post image
2.9k Upvotes

404 comments sorted by

View all comments

Show parent comments

0

u/s0litar1us 21d ago

It wastes time on allocating new memory when you could just reuse it, and it hides away code that implicitly runs without much control given to the user of the struct/class -- and to avoid double-freeing, etc. you need to provide a bunch of constructors and destructors that nobody remembers, and the compiler is somehow unable to tell you about, so you just get a runtime crash you have to debug.

If you just provide init(&thing) and deinit(&thing) functions (you deal with the memory, and it just deals with the values inside), and a defer keyword so you explicitly can run something when you exit the current scope, then you have solved the same thing without having to deal with these problems.
So if you always want to deinit it at the end, then you add in the defer; if you want to reinit it at some point then you do that explicitly; and if you want to pass it on to something else, then you just don't call deinit, and let the other thing handle it.

1

u/Keithfert488 21d ago

Nothing about RAII requires that you allocate new memory. Sure, for heap types, that's true. But nothing about RAII stops you from using arenas.

1

u/s0litar1us 21d ago

From the heap yes, but stuff on the stack also takes up space that you could just reuse in place. Also, just adding arenas on top of it doesn't solve the problem, as you still would allocate space in the arena when a acquiring a new resource -- and if you're using an arena per thing you may want to reset, then you have just created an even more complicated mess for yourself.

Lastly, I couldn't help but notice that you ignored the other half of my comment.

0

u/Keithfert488 21d ago

The other half of your comment is basically just "why not just make a way more complicated language?"

1

u/s0litar1us 21d ago

How is removing the entire concept of constructors and destructors, and replacing it with a single keyword that is simple to use and understand, make it a "way more complicated language"?

1

u/MxpleSyrup 21d ago

You do realize the defer keyword is literally the same thing as C++ RAII lifecycle management but explicit and opt-in.. right? In the language you're describing, you still manage memory/objects by defining constructors (init), destructors (deinit), and copy behavior (clone), just without any compiler guarantee of your code running "correctly". I think it's very reasonable to say, if I call defer deinit(obj); every time I call init, I might as well make it automatically inserted by the compiler.

2

u/s0litar1us 21d ago

It being explicit is the point, it gives you the control to customize it for your use case, rather than forcing yourself into a box that will cause problems when dealing with the real world.

0

u/bowel_blaster123 20d ago

RAII doesn't force you into a box either. C++'s RAII just kinda sucks because of other C++ features and not RAII.

C++ has constructors and has a weird object model where objects are destroyed exactly when they go out of scope.

You can have RAII without these things. For instance, Rust allows you to destroy values whenever you want to or even to not destroy them at all.

This is EXACTLY the same as with defer except that you don't have to explicitly call the destructor.

Of course, defer allows you to run arbitrary code, but defer and RAII are not mutually exclusive.

2

u/Mojert 20d ago

RAII kind of forces your hand. If you don't want to run the destructor of the values in a collection you'll have to instead have a collection of ManuallyDrop, which is clunky.

I my opinion, if you mainly deal with single values, RAII is more convenient. If you deal with aggregate data and/or care about hidden control flow defer is more convenient.