Live data from Hacker News

A Defer Mechanism for C

gustedt.wordpress.com

171–180 of 248 posts

Re: A Defer Mechanism for C

#171
post #91
post #47

Earlier quoted context omitted.

It shouldn't be. std::unique_ptr is very clear. (std::shared_ptr should be used only when absolutely required and should be kept under close watch the whole time.)

searches codebase I'm working on... finds thousands and thousands of std::shared_ptr (many involve a typedef, so there are even more...) eep! Should I be alarmed?

Not necessarily. The concern about when the shared_ptr'd value runs its destructor only matters if the value's destructor is something you care about.

If you have a situation where a value needs to be shared between multiple other values, but also the value is trivial enough that it doesn't matter when it's destroyed or what it does when it's destroyed, but also the value is not so trivial that you can copy it instead of using a refcounting pointer, then std::shared_ptr is fine.

Re: A Defer Mechanism for C

#172
post #91

Earlier quoted context omitted.

searches codebase I'm working on... finds thousands and thousands of std::shared_ptr (many involve a typedef, so there are even more...) eep! Should I be alarmed?

Not necessarily. The concern about when the shared_ptr'd value runs its destructor only matters if the value's destructor is something you care about. If you have a situation where a value needs to be shared between multiple other values, but also the value is trivial enough that it doesn't matter when it's destroyed or what it does when it's destroyed, but also the value is not so trivial that you can copy it instea…

"Fine" is probably pushing it, but "not the biggest problem you are likely to have" is probably true. But, like, it's easy to accidentally get yourself into situations where somebody forgot to use std::weak_ptr somewhere and you start leaking memory.

Unless you know you must share objects with multiple potential owners, though, std::unique_ptr is a lot wiser.

Re: A Defer Mechanism for C

#173

Earlier quoted context omitted.

Not necessarily. The concern about when the shared_ptr'd value runs its destructor only matters if the value's destructor is something you care about. If you have a situation where a value needs to be shared between multiple other values, but also the value is trivial enough that it doesn't matter when it's destroyed or what it does when it's destroyed, but also the value is not so trivial that you can copy it instea…

"Fine" is probably pushing it, but "not the biggest problem you are likely to have" is probably true. But, like, it's easy to accidentally get yourself into situations where somebody forgot to use std::weak_ptr somewhere and you start leaking memory. Unless you know you must share objects with multiple potential owners, though, std::unique_ptr is a lot wiser.

Yes, when I wrote:

>but also the value is trivial enough that it doesn't matter when it's destroyed or what it does when it's destroyed"

that precludes the value from having other refcounting pointers that could then create cycles and leak.

Re: A Defer Mechanism for C

#174

Earlier quoted context omitted.

it's control flow. What you are saying is like saying "while loops are implicit: you can no longer reason about code; you now must think about the state of the check boolean to see if it will trigger the hidden behaviour of going back to the top of the loop because there's no explicit "go back to the top of the block" statement.

With a while loop, to know what happens at the bottom of the block, you only need to check the top of the block. With defer, to know what happens at the bottom of the block, you need to check the entire contents of the block.

> With a while loop, to know what happens at the bottom of the block, you only need to check the top of the block.

Anyway, what could possibly happen at the end of a while loop, besides going back to the begining for the test?

Besides, if you have a bug in your code, you will have to look at the whole block anyway.

Re: A Defer Mechanism for C

#175

Earlier quoted context omitted.

> One of the key interest of C compared to more recent languages is that everything is explicit. With macros this is not exactly true. I gesture towards the GObject system for an extremely complex situation in big important production software.

I agree. I have tried to come up with some reasonable way to constrain macros, but its really hard!

The way to do it is, survey your macro use to identify common patterns, specify them formally, and then write a computer program that allows those patterns specifically but no others. In other words, design a higher-level language. ;)

Re: A Defer Mechanism for C

#176
post #78
post #46

In its current form, this is really stupid, because of something like this: guard { for (int i = 0; i Now the compiler has to: 1. implement some side of capture/closure mechanism to keep all the 'i's to the end of the guard block 2. do dynamic allocation to store the closures so they can be executed at the end did the scope 1 seems like too much work for such a feature, and 2 is a massive no. Implicit dynamic allocat…

I suspect it will come with some really big caveats. For instance what you wrote shouldn't compile, because i's storage duration doesn't extend to the end of the guard block. If you write guard { int i; for (i=0; i I would expect foo(n) to be called n times. That is, variables won't be captured, it would work literally as if you wrote "foo(i)" n times at the end of the guard block. It's a footgun, but everything in C…

> What order the defer blocks are stored in is implementation-defined.

But the order they're executed in would have to be defined, lest we build ourselves another major bug generator.

Re: A Defer Mechanism for C

#177

Earlier quoted context omitted.

Sure. But defer just changes the problem from forgetting to write free to forgetting to write defer. So we’re not really talking about provably correct solutions... just things that can work. And I think a context or just manually freeing can work nicely.

> defer just changes the problem from forgetting to write free to forgetting to write defer. That's the case only the first time you write code: { foo *f = new_foo(); // step 1 /* lots of code */ // step 3 free(f); // step 2 } vs { foo *f = new_foo(); // step 1 defer free(f); // step 2 /* lots of code */ // step 3 } Sure, in both cases you can forget step 2. But what about review ? With defer, the init and cleanup co…

I think this example demonstrates the opposite of what you intended. Defer doesn't give you anything that you can't already do. In your last four code blocks, you demonstrated three alternate ways to implement the functionality you want without defer. Defer is just a slightly different, arguably nicer fourth way to implement the same code.

Language features should be orthogonal. A new language feature should add something that is not possible or extremely painful to do with the existing language features. I just don't see how these minor syntax adjustments warrant a new feature, especially one with as much complexity and corner cases as this defer proposal.

(The real answer to "why defer?", of course, is that the authors need it to implement panic/recover. This proposal should stop masquerading as a defer mechanism for C and instead call itself what it really is: exceptions for C.)

Re: A Defer Mechanism for C

#179
post #20

Earlier quoted context omitted.

The whole point is that it's much easier to NOT forget defer (which goes right after the resource acquisition line), than to forget to free the resource (which happens much further down the function). So it's immediately better compared to the current C situation. As for compared to RAII? Well, thats one failure mode for defer (forgetting it), whereas there are dozens of ways to mess RAII...

I made no comparison between “defer” and the current C situation. In comparison to RAII, “defer” as a language feature is a kludge. Mainly because RAII completely solves the problem of correct resource cleanup for API users while “defer” does not.

RAII is a delight when it comes to local heap memory. However, if you want to pair fclose with a fopen call then you need to wrap fopen in a type and make the destructor call fclose. This is totally fine and I like it a lot in C++ and Rust, but it doesn't gel with existing C apis. Therefore I think defer is a good choice for C regardless of what I might choose were I to be implementing a language from scratch.

Re: A Defer Mechanism for C

#180
I can't say anything about whether this is a good idea in general or not, but if they are going to do it, then why not just combine the allocation with the defered free into a single syntax ...

'void* x = defer_free_malloc (...);'

Post reply on HN