Live data from Hacker News

Defer: Resource cleanup in C with GCCs magic

oshub.org

11–20 of 99 posts

Re: Defer: Resource cleanup in C with GCCs magic

#12
post #6

I don't understand why people insist on simulating a poor substitute for RAII with a feature that is itself almost decent RAII. > If malloc fails and returns NULL, the cleanup function will still be called, and there’s no simple way to add a guard inside free_ptr. free(NULL) is a no-op, this is a non-issue. I don't know what's so hard about a single if statement anyway even if this were an issue.

`free(NULL);` will crash on some platforms that gcc supports, I believe.

That feels like a "citation needed", since that would be very clear violation of the C spec and thus a rather serious bug in the standard library for that platform.

Re: Defer: Resource cleanup in C with GCCs magic

#13

I don't understand why people insist on simulating a poor substitute for RAII with a feature that is itself almost decent RAII. > If malloc fails and returns NULL, the cleanup function will still be called, and there’s no simple way to add a guard inside free_ptr. free(NULL) is a no-op, this is a non-issue. I don't know what's so hard about a single if statement anyway even if this were an issue.

> I don't understand why people insist on simulating a poor substitute for RAII with a feature that is itself almost decent RAII.

Because it’s nowhere near “almost decent RAII” and RAII requires a lot more machinery which makes retrofitting RAII complicated, especially in a langage like C which is both pretty conservative and not strong on types:

- RAII is attached to types, so it’s not useful until you start massively overhauling code bases e.g. to RAII FDs or pointers in C you need to wrap each of them in bespoke types attaching ownership

- without rust-style destructive moves (which has massive langage implications) every RAII value has to handle being dropped multiple times, which likely means you need C++-style copy/move hooks

- RAII potentially injects code in any scope exit, which I can’t see old C heads liking much, if you add copy/move then every function call also gets involved

- Because RAII “spreads” through wrapper types, that requires surfacing somehow to external callers

Defer is a lot less safe and “clean” than RAII, but it’s also significantly less impactful at a language level. And while I very much prefer RAII to defer for clean-slate design, I’ve absolutely come around to the idea that it’s not just undesirable but infeasible to retrofit into C (without creating an entirely new language à la C++, you might not need C++ itself but you would need a lot of changes to C’s semantics and culture both for RAII to be feasible).

https://thephd.dev/just-put-raii-in-c-bro-please-bro-just-on... has even more, mostly from the POV of backporting C++ so some items have Rust counterpoints… with the issue that they tend to require semantics changes matching Rust which is also infeasible.

Re: Defer: Resource cleanup in C with GCCs magic

#14

I don't understand why people insist on simulating a poor substitute for RAII with a feature that is itself almost decent RAII. > If malloc fails and returns NULL, the cleanup function will still be called, and there’s no simple way to add a guard inside free_ptr. free(NULL) is a no-op, this is a non-issue. I don't know what's so hard about a single if statement anyway even if this were an issue.

poor?

If I use RAII I'd need to have a struct/class and a destructor.

If I use defer I'd just need the keyword defer and the free() code. It's a lot more lean, efficient, understandable to write out.

And with regards to code-execution timing, defer frees me from such a burden compared to if-free.

Re: Defer: Resource cleanup in C with GCCs magic

#15

I don't understand why people insist on simulating a poor substitute for RAII with a feature that is itself almost decent RAII. > If malloc fails and returns NULL, the cleanup function will still be called, and there’s no simple way to add a guard inside free_ptr. free(NULL) is a no-op, this is a non-issue. I don't know what's so hard about a single if statement anyway even if this were an issue.

> I don't understand why people insist on simulating a poor substitute for RAII with a feature that is itself almost decent RAII.

RAII doesn't make sense without initialization.

Are you proposing C should add constructors, or that C should make do without defer because it can't add constructors?

Re: Defer: Resource cleanup in C with GCCs magic

#16

I don't understand why people insist on simulating a poor substitute for RAII with a feature that is itself almost decent RAII. > If malloc fails and returns NULL, the cleanup function will still be called, and there’s no simple way to add a guard inside free_ptr. free(NULL) is a no-op, this is a non-issue. I don't know what's so hard about a single if statement anyway even if this were an issue.

[deleted]

Re: Defer: Resource cleanup in C with GCCs magic

#17
post #6

Earlier quoted context omitted.

`free(NULL);` will crash on some platforms that gcc supports, I believe.

can we just do `if(*ptr == NULL) return;` ?

No, because optimizing compilers are free to elide the check. https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#ind...

Re: Defer: Resource cleanup in C with GCCs magic

#18
Nested functions are cool, although not supported by clang.

However they rely on Trampolines: https://gcc.gnu.org/onlinedocs/gccint/Trampolines.html

And trampolines need executable stack:

> The use of trampolines requires an executable stack, which is a security risk. To avoid this problem, GCC also supports another strategy: using descriptors for nested functions. Under this model, taking the address of a nested function results in a pointer to a non-executable function descriptor object. Initializing the static chain from the descriptor is handled at indirect call sites.

So, if I understand it right, instead trampoline on executable stack, the pointer to function and data is pushed into the "descriptor", and then there is an indirect call to this. I guess better than exec stack, but still...

Re: Defer: Resource cleanup in C with GCCs magic

#19

Earlier quoted context omitted.

can we just do `if(*ptr == NULL) return;` ?

No, because optimizing compilers are free to elide the check. https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#ind...

Not on all platforms! If you’re writing portable code targeting a lot of embedded platforms then you don’t want to rely on this optimization.

Re: Defer: Resource cleanup in C with GCCs magic

#20

Earlier quoted context omitted.

can we just do `if(*ptr == NULL) return;` ?

No, because optimizing compilers are free to elide the check. https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#ind...

I'm not quite familar with this flag, but this

>so that if a pointer is checked after it has already been dereferenced, it cannot be null.

sound to me that if i've never deref the pointer anytime before(e.g the null check is at the beginning of function), the compiler won't remove this check.

Post reply on HN