Live data from Hacker News

Defer: Resource cleanup in C with GCCs magic

oshub.org

81–90 of 99 posts

Re: Defer: Resource cleanup in C with GCCs magic

#81

Earlier quoted context omitted.

>> Are you suggesting only use C++ over C in all situations? > Yes. You cannot imagine any situation where that proposal is a non-starter? Or a deal-breaker?

Not in most places. Even GCC moved to build their C code as C++.

> Not in most places.

So you can imagine that C++ instead of C is a deal-breaker or show-stopper in some places, right?

Now that we both agree that there are some communities who won't move off C, do you believe that those communities should never get any upgrade, security fixes, etc?

Re: Defer: Resource cleanup in C with GCCs magic

#82
post #60

Slightly off-topic, but: The fact that go "lifts" the deferred statement out of the block is just another reason in the long list of reasons that go shouldn't exist. Not only is there no protection against data-races (in a language all about multithreading), basically no static checking for safety, allocation and initialization is easy to mess up, but also defer just doesn't work as it does in C++, Rust, Zig, and any…

One of those languages being D, which invented it (well, Andrei Alexandrescu did) under the name `scope(exit)` (there's also `scope(failure)` which is like Zig's `errdefer` and `scope(success)` which no other language has AFAIK).

Re: Defer: Resource cleanup in C with GCCs magic

#83
post #62

Earlier quoted context omitted.

I encourage you to read ( at least ) this section of this blog before making simplistic suggestions: https://thephd.dev/just-put-raii-in-c-bro-please-bro-just-on... How do you mandate initialization, handle copies, move objects, prevent double frees? What's RAII without any of that?

You mandate it like you mandate anything else in C. You don't. You pick C because you want a language that doesn't require a variable to be initialised before mutably referencing it, and you write your defer statements or "destructors" defensively, expecting that a variable could be in any state when it comes time to dispose of it. Or if you find that unacceptable, you accept that C isn't the language you want. There…

There's no way to write a "destructor" defensively, if the contents of memory it is trying to "destroy" are undefined.

Whereas it's perfectly possible to only defer a statement when you know the "object" has been properly initialized.

That's why defer makes sense in a language like C (even Go), but RAII does not.

Re: Defer: Resource cleanup in C with GCCs magic

#84
post #9

Earlier quoted context omitted.

It shouldn't https://pubs.opengroup.org/onlinepubs/7908799/xsh/free.html >If ptr is a null pointer, no action occurs.

While I agree it shouldn't, that particular document is the UNIX specification, not the C specification, so it does not apply to C compilers on non-UNIX platforms.

free(NULL) is a noop ever since C89 (I was on the standards committee, X3J11).

Re: Defer: Resource cleanup in C with GCCs magic

#85
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.

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

No, of course it won't. `free(NULL)` has been a noop ever since C89 (and before, for that matter).

Re: Defer: Resource cleanup in C with GCCs magic

#86
post #6

Earlier quoted context omitted.

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

> `free(NULL);` will crash on some platforms that gcc supports, I believe. I'm pretty certain that `free(NULL)` is part of the C99 standard, so compiler vendors have had 25 years to address it. If your `free(NULL)` is crashing on a certain platform, you probably have bigger problems, starting with "Compiler that hasn't been updated in 25 years".

It's in C89 (I was on the standards committee, X3J11).

Re: Defer: Resource cleanup in C with GCCs magic

#87
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;` ?

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

No, certainly not, but you can do

`if(ptr == NULL) return;`

which is correct but unnecessary since `free` is required to do that check.

Re: Defer: Resource cleanup in C with GCCs magic

#88

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...

Yes, but `*ptr == NULL` is just plain wrong ... it should be `ptr == NULL` ... but that test is redundant since `free` is required to do it.

Re: Defer: Resource cleanup in C with GCCs magic

#89
post #83

Earlier quoted context omitted.

You mandate it like you mandate anything else in C. You don't. You pick C because you want a language that doesn't require a variable to be initialised before mutably referencing it, and you write your defer statements or "destructors" defensively, expecting that a variable could be in any state when it comes time to dispose of it. Or if you find that unacceptable, you accept that C isn't the language you want. There…

There's no way to write a "destructor" defensively, if the contents of memory it is trying to "destroy" are undefined. Whereas it's perfectly possible to only defer a statement when you know the "object" has been properly initialized. That's why defer makes sense in a language like C (even Go), but RAII does not.

I agree with everything you've said, except the conclusion: C can't add proper safe RAII, but being "proper and safe" is not a threshold C even tries to uphold.

Re: Defer: Resource cleanup in C with GCCs magic

#90
post #83

Earlier quoted context omitted.

There's no way to write a "destructor" defensively, if the contents of memory it is trying to "destroy" are undefined. Whereas it's perfectly possible to only defer a statement when you know the "object" has been properly initialized. That's why defer makes sense in a language like C (even Go), but RAII does not.

I agree with everything you've said, except the conclusion: C can't add proper safe RAII, but being "proper and safe" is not a threshold C even tries to uphold.

But would a destructor that runs automagically when a value goes out of scope, even if it's not properly initialized (and with zero regards for copies or moves) be in any way better than a defer that's explicitly called after it is initialized?

Cause, like, that's the entire thread.

Post reply on HN