Live data from Hacker News

A Defer Mechanism for C

gustedt.wordpress.com

191–200 of 248 posts

Re: A Defer Mechanism for C

#191

Re: Should object values be captured? The results from 387 responses (to a Twitter poll) show a 2:1 preference for the value being read at the time the deferred statements are executed (66.9%) rather than when the defer statement encountered(33.1%). Since both options - by value and by reference - may be viewed as reasonable or desirable, neither should be a default. Instead, they both should be using a special synta…

I would prefer an explicit capture at the beginning of the 'defer', as in:

  defer[p] free(p);
Instead of specifying it separately for each variable use.

Re: A Defer Mechanism for C

#192
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…

No, actually none of that. That code has a constraint violation: it uses the variable i outside of its scope. Even if i would be declared on the same level as the guard, this sequence of deferred statements would not do good, but also not much harm. It would call foo with all the same value for i, namely n.

To have a good example where defer inside a loop actually does something, you'd have to capture the value of i. We also have a macro for that in the reference implementation, but that has a much more specialized scope of use.

Re: A Defer Mechanism for C

#193

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 (...);'

I came to say this too, it seemed like an obvious evolution. I find the "randomness" of the defer-statement a bit scary, like there is too much freedom. There's no guarantee that you're deferring the proper code to free the resource, which somehow should be the default.

Not at all sure of the proper syntax, but at least tying it together with something like

    void * const x = DEFER(malloc(...), free);
would make sense. In a more high-level language with interfaces, there should be a way to tie together the creation and destruction into a combined type, and just do

    obj = acquire SomeType(...);
And then 'acquire' should take care that the type to the right implements the interface, and automatically add a deferred call to the proper freeing method. Hm. I guess I just invented some kind of garbage collection, bummer.

Re: A Defer Mechanism for C

#194
post #2

Despite being convenient,I have the feeling that it might be a bad idea. One of the key interest of C compared to more recent languages is that everything is explicit. With a finger you can follow the code as it runs and know exactly what is going on and when exactly. At the opposite, there is c++ that does a lot of things automagically. And it is often hard to understand why you suddenly get a segfault out of blue,…

> One of the key interest of C compared to more recent languages is that everything is explicit. With a finger you can follow the code as it runs and know exactly what is going on and when exactly.

I would suggest functions like atexit and pthread_cleanup_push as well established counterexamples. Granted this is not a perfect comparison because these are implementable without extending the c language; however, I think they have the same general idea of "defering" cleanup. I think the proposed defer functionality is actually more readable because the defer command will be written much closer to where it will be exited. Compare this to atexit() which may be put anywhere.

Re: A Defer Mechanism for C

#195
post #2

Despite being convenient,I have the feeling that it might be a bad idea. One of the key interest of C compared to more recent languages is that everything is explicit. With a finger you can follow the code as it runs and know exactly what is going on and when exactly. At the opposite, there is c++ that does a lot of things automagically. And it is often hard to understand why you suddenly get a segfault out of blue,…

One of the key interest of C compared to more recent languages is that everything is explicit. With a finger you can follow the code as it runs and know exactly what is going on and when exactly.

This has not been true in many years. C appears to be such a language, but optimizing compilers have learned how to find and optimize undefined behavior in code that most C programmers don't realize is unsafe. As a result there can be a considerable gap between the code as clearly intended, and the code that will be generated.

See https://blog.regehr.org/archives/213 for more on this. Including real world examples of things like validation checks being elided by the compiler, leading to real-world vulnerabilities in programs which clearly have checks to avoid exactly those vulnerabilities.

Re: A Defer Mechanism for C

#196
post #137
post #89

Earlier quoted context omitted.

Which is why we want it to be standardized. It's already widely used on Linux and BSDs, the big compilers already implement the underlying functionality (because it's needed by C++), GCC and LLVM implement the exact same extension in an identical way, it does everything that people need, so let's make it work officially.

Still there is a life beyond UNIX clones and gcc/clang. The C compiler vendor for some embedded CPU with homegrown C compiler for their in-house OS also has a seat at ISO table. While people here might not care, ISO does.

I agree. So go with the well-established widely used change, not the baroque and ill-defined proposal in the original post.

Re: A Defer Mechanism for C

#197

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 (...);'

[deleted]

Re: A Defer Mechanism for C

#198

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.

What? Any statement inside a while loop could mutate the loop variable and then all bets are off.

You have to check every line of a while loop to know what’s going on. Heck, another thread could hold a pointer aliasing the loop variable and then mutate it, causing the loop to terminate for no obvious reason.

Re: A Defer Mechanism for C

#199

Earlier quoted context omitted.

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.

What? Any statement inside a while loop could mutate the loop variable and then all bets are off. You have to check every line of a while loop to know what’s going on. Heck, another thread could hold a pointer aliasing the loop variable and then mutate it, causing the loop to terminate for no obvious reason.

My point is that you know at the end of the while loop, it's going to test the loop variable you wrote at the beginning, no matter what's in the loop body. The fact that other things could change the variable isn't relevant. With defer, you don't know what will happen at the end of a block without looking through the whole thing.

Re: A Defer Mechanism for C

#200
post #6

Earlier quoted context omitted.

> One of the key interest of C compared to more recent languages is that everything is explicit. There's nothing implicit about defer.

Every defer statement is ultimately pushing a lambda into some stack that is executed when the defer block is exited. With an exception of setjmp/longjmp, I can't think of an existing C construct with similar run-time complexity.

Is it actually a lambda, or is it just essentially appending statements to the end of the scope?
Post reply on HN