Live data from Hacker News

A Defer Mechanism for C

gustedt.wordpress.com

81–90 of 248 posts

Re: A Defer Mechanism for C

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

This isn't really true. If you're capturing by reference, you can easily say that defer can only be called on variables declared in scopes no deeper than the beginning of the defer block and you still have a very useful feature. If you're capturing by value, the "closures" are probably just getting created in the stack like normal auto variables. Either way, this doesn't really seem to be a deal breaker.

Re: A Defer Mechanism for C

#82
post #61
post #12

Please just standardize the already existing attribute((cleanup)) mechanism which is already being used by lots of Linux software. This new mechanism is incompatible while bringing no benefits.

Defer has the benefit of being dynamic vs the scope tied cleanup.

I think it depends what problem you're trying to solve. If you're just trying to kill kernel-style GOTO cleanup pyramids, then having it tied to scope with no unwinding or anything dynamic is perfectly adequate.

Re: A Defer Mechanism for C

#83
post #54

I’ve always considered “defer” an inelegant kludge in comparison to RAII for automatic cleanup of resources. It’s surprising that the C standards committee is considering adding that to the language. Then again, nearly none of the syntactic C features post-C89 have been very compelling or widely adopted.

RAII is a special case of defer, due to how it abuses constructors and destructors to hook into the points of entering and exiting scope. You could write a RAII implementation in terms of defer but not the other way around. RAII doesn't help with a generic pair of init and deinit functions, such as malloc() and free() for example, unless you wrap your mallocs into "memory objects" or something. You can't do anything…

> RAII doesn't help with a generic pair of init and deinit functions, such as malloc() and free() for example,

people have been writing RAII scope_exit classes for at least 20 years to do exactly this.

> You can't do anything with RAII unless you wrap your stuff into objects which just forces the OO crap on everything regardless of whether it's a good fit for the OO paradigm.

wrapping something in an object does not make it OO. For example there is nothing object oriented about std::unique_ptr.

Re: A Defer Mechanism for C

#84
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,…

> With a finger you can follow the code as it runs and know exactly what is going on and when exactly.

Oh yeah?

https://www.youtube.com/watch?v=Gv2I7qTux7g?t=29m21s

Re: A Defer Mechanism for C

#85
post #71
post #52

Earlier quoted context omitted.

> As an example of my point, I would refer to the 'garbage collection' issues of a language like 'java' Two languages could hardly be less alike than Java and C++ - the latter is not garbage collected and where destructors are called is completely predictable.

You’re missing the point. The two are alike in that something significant is happening that you as the programmer did not explicitly tell it to do. The specific mechanism really isn’t an important distinction here.

If you write a destructor then you know exactly under what circumstances in C++ code it will be used (this is one of the major features of the language). This specific mechanism is extremely important.

Re: A Defer Mechanism for C

#86
post #13

Earlier quoted context omitted.

defer is great for many use cases, available in Go, Swift and other languages, and nothing like a kludge. If anything RAII is unfit for C (which doesn't have classes), and in itself, a kludge (it's an idiom, not a language feature).

I would strongly disagree on RAII being a kludge in C++. The language feature that enables it is deterministic destructors, whose primary purpose is to ensure that allocated resources are deallocated. RAII is one particular use of destructors. The primary goal is to have the object be the thing that owns a resource, not the calling scope. In terms of usability, destructors allow for resource management that is far ea…

I do feel that RAII is a little bit ruined by the fact that you cannot declare anonymous object instances.

For example, I cannot write:

    lock (mutex);
Expecting to declare an anonymous lock with the mutex passed in, as this gets parsed as a declaration of a lock called mutex (hopefully lock doesn’t have a default constrictor and I at least get an error). Instead I have to bake my lock:

    lock l(mutex);
Often I have objects that only exist for RAII and it’s a little bit annoying to have to give them dummy names.

Re: A Defer Mechanism for C

#87

Earlier quoted context omitted.

Defer is more explicit than RAII, so a better fit for the very explicit C language

It’s even more explicit to just call your cleanup routines manually, so by that logic “defer” is inferior to existing methods of handling cleanup in C

subroutine calls requires implicit allocation and deallocation of stack frames. Real Programmers™ use goto and manage the stack by hand.

Re: A Defer Mechanism for C

#88
post #69

Earlier quoted context omitted.

guard/defer is semantically and syntactically as explicit (or implicit) as C's automatic storage class ( https://en.cppreference.com/w/c/language/storage_duration ), which is the default storage class.

Only if you include dynamically sized arrays, which are deprecated because of their problematic allocation behaviour.

I don't believe that VLAs are actually deprecated as such, but have been moved to an "optional" feature for implementation in C11. There's a feature macro to check, __STDC_NO_VLA__, but I don't think the feature is actually disappearing from the standard any time soon.

Re: A Defer Mechanism for C

#89
post #66
post #12

Please just standardize the already existing attribute((cleanup)) mechanism which is already being used by lots of Linux software. This new mechanism is incompatible while bringing no benefits.

ISO has to care about much more platforms than just Linux.

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.

Re: A Defer Mechanism for C

#90
post #71
post #52

Earlier quoted context omitted.

> As an example of my point, I would refer to the 'garbage collection' issues of a language like 'java' Two languages could hardly be less alike than Java and C++ - the latter is not garbage collected and where destructors are called is completely predictable.

You’re missing the point. The two are alike in that something significant is happening that you as the programmer did not explicitly tell it to do. The specific mechanism really isn’t an important distinction here.

There is no guarantee when a Java finalizer will run, whereas a C++ destructor is guaranteed to run based on the code that you write. That's a big difference which has practical implications, using something with non-guaranteed behaviour as an example of why something with guaranteed behaviour is hard to predict seems like a misunderstanding.
Post reply on HN