Live data from Hacker News

Defer: Resource cleanup in C with GCCs magic

oshub.org

21–30 of 99 posts

Re: Defer: Resource cleanup in C with GCCs magic

#21
post #19

Earlier quoted context omitted.

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.

It's a platform-agnostic optimization in case of GCC so if your embedded Linux toolchain is based on GCC, and most of them are, it's pretty much the case that it will have this optimization turned on by default.

> This option is enabled by default on most targets. On AVR and MSP430, this option is completely disabled.

Re: Defer: Resource cleanup in C with GCCs magic

#22

Earlier quoted context omitted.

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.

Since the compiler will merge/fold what it appears to be a different logic sections of your code into a single one, you can never be sure what the release build codegen looks like unless you read the assembly.

Re: Defer: Resource cleanup in C with GCCs magic

#23
Testing with Jen's macro this was based on, and found that the always_inline was redundant under even -O1 (https://godbolt.org/z/qoh861Gch via the examples from N3488 as became the baseline for the TS for C2y, which has recently a new revision under N3687), so there's an interesting trade-off between visibly seeing the `defer` by not not-inlining within the macro under an -O0 or similar unoptimised build, since with the inlining they are unmarked in the disassembly. But, there's an interesting twist here, as "defer: the feature" is likely not going to be implemented as "defer: the macro", since compilers will have the keyword (just `defer` in TS25755, or something else that uses a header for sugared `defer`) and may see the obvious optimised rewrite as the straightforward way of implementing it in the first place (as some already have), meaning we can have the benefit of the optimised inline with the opportunity to also keep it clearly identifiable, even in unoptimised and debug builds, which would certainly be nice to have!

Re: Defer: Resource cleanup in C with GCCs magic

#24
post #4

Then there is the proposal to add standard `defer` to C2y[0] [0] https://thephd.dev/c2y-the-defer-technical-specification-its...

Jen's macro that this was based on was an implementation of his own proposal (N3434) for `defer`, which was one of a few preceding what finally became TS25755! So, yes, C2y is lined up to have "defer: the feature", but until then, we can explore "defer: the macro" (at least on GCC builds, as formulated).

Re: Defer: Resource cleanup in C with GCCs magic

#25
post #4

Then there is the proposal to add standard `defer` to C2y[0] [0] https://thephd.dev/c2y-the-defer-technical-specification-its...

It's been implemented in GCC(in review)[1], onramp[2] and my own slimcc[3]!

[1] https://patchwork.ozlabs.org/project/gcc/list/?series=470822

[2] https://github.com/ludocode/onramp

[3] https://github.com/fuhsnn/slimcc

Re: Defer: Resource cleanup in C with GCCs magic

#27
post #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?

> RAII doesn't make sense without initialization.

Rust has RAII and does not have constructors.

Re: Defer: Resource cleanup in C with GCCs magic

#28

I'm always suspicious of exotic features that could fail in surprising ways.

Well, each `defer` proposal for C agreed that it shouldn't be done the way Go does it, and should just be "run this at the end of lexical scope", so it'll certainly be less surprising than the alternative... and far easier to implement correctly on the compiler side... and easier to read and write than the corresponding goto cleanup some rely on instead. Honestly, I feel like it becomes about as surprising as the `i++` expression in a `for` loop, since that conceptually is also moved to the end of the loop's lexical scope, to run before the next conditional check. Of course, a better way of representing and visualising the code, even if optionally, would help show where and when these statements run, but a standard feature (especially with some of the proposed safety mechanisms around jumps and other ways it could fail in surprising ways) it would hardly seem exotic, and inversely is quite likely to expose things currently fail in surprising ways precisely because we don't have a simple `defer` feature and so wrote something much more complicated and error-prone instead.

So, I completely understand the sentiment, but feel that `defer` is a feature that should hopefully move in the opposite direction, allowing us to rely on less exotic code and expose & resolve some of the surprising failure paths instead!

Re: Defer: Resource cleanup in C with GCCs magic

#29
post #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 fun…

They only need an executable stack when they're not inlined.

The always_inline keyword takes care of that here.

Re: Defer: Resource cleanup in C with GCCs magic

#30
post #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.

> If I use defer I'd just need the keyword defer and the free() code.

Yeah, and not accidentally forgetting to call it. That's the big part. And before "True Scotsman will always free/close/defer!" - No, no they won't.

Unless the compiler screams at them, or its enforced via syntax constructs, it will always slip through the cracks.

Post reply on HN