Live data from Hacker News

C: Simple Defer, Ready to Use

gustedt.wordpress.com

21–30 of 157 posts

Re: C: Simple Defer, Ready to Use

#22

Very nice, using the goto trick to perform cleanups always felt dirty to me.

I use a few strategies instead of goto:

(1) For simpler cases, wrap in do {} while (0) and break from the loop

(2) For multiple cleanups, use same technique combined with checks to see if the cleanup is required. E.g. if (f != null) fclose (f)

(3) put the rest of the stuff in another function so that the exit code must run on the way out.

In 35 years of coding C/C++, I've literally never resorted to goto. While convenient, this new defer command looks like the kind of accidental complexity that templates brought to C++. That is, it provides a simple feature meant to be solve simple problems in a simple way that accidentally allows architecture astronauts the ability to build elaborate footguns.

Re: C: Simple Defer, Ready to Use

#23

I really, really do not like what that could do to the readability of code if it was used liberally. It's like GOTOs, but worse, because it's not as visible. C++'s destructors feel like a better/more explicit way to handle these sorts of problems.

But thats C++

Re: C: Simple Defer, Ready to Use

#24

I really, really do not like what that could do to the readability of code if it was used liberally. It's like GOTOs, but worse, because it's not as visible. C++'s destructors feel like a better/more explicit way to handle these sorts of problems.

But thats C++

I am aware. I'm just pointing it out because they're similar ideas.

Re: C: Simple Defer, Ready to Use

#25
The C++ lambda version can be a foot gun: https://godbolt.org/z/Wd66GcrdG, if the return value is a struct, NRVO (named return value optimization) may be applied and the lambda will be called in different order.

As for the n3434 proposal, given that the listed implementation experiences are all macro-based, wouldn't it be more easily adopted if proposed as a standard macro like ?

Re: C: Simple Defer, Ready to Use

#26

Unfortunately, this requires an executable stack, and only works on gcc, though an alternate implementation can work on clang. After a few attempts at defer, I ended up using a cleanup macro that just takes a function and a value to pass to it: https://github.com/aws-greengrass/aws-greengrass-lite/blob/8... Since the attribute or a function-like macro in the attribute position broke the c parsing in some tooling, I m…

It does not need an executable stack: https://godbolt.org/z/K1GTa4jh4

Re: C: Simple Defer, Ready to Use

#28

I really, really do not like what that could do to the readability of code if it was used liberally. It's like GOTOs, but worse, because it's not as visible. C++'s destructors feel like a better/more explicit way to handle these sorts of problems.

Destructors are hidden control flow, and can be non-obvious for structs from other files. I find they make code significantly harder to follow than in plain C. Defer does not have the problem, as all the logic in your function is explicitly there.

Re: C: Simple Defer, Ready to Use

#29
post #16
post #14

Earlier quoted context omitted.

Dijkstra was not wrong. Modern programmers are wrong in thinking that the goto that they use is what Dijkstra was talking about, merely because of the fact it happens to be called the same thing. I mean, I get how that can happen, no sarcasm, but the goto Dijkstra was talking about and what is in a modern language is not the same. https://jerf.org/iri/post/2024/goto/ The goto Dijkstra is talking about is dead. It liv…

Or the tl;dr in modern parlance Dijkstra was railing against the evils of setjmp.

Sometimes setjmp is useful and I had occasionally used it, but usually it is not needed. There is certain considerations you must make in order to be careful when you are using setjmp though.

(Free Hero Mesh uses setjmp in the execute_turn function. This function will call several other functions some of which are recursive, and sometimes an error occurs or WinLevel or LoseLevel occurs (even though these aren't errors), in which case it will have to return immediately. I did try to ensure that this use will not result in memory leaks or other problems; e.g. v_set_popup allocates a string and will not call longjmp while the string is allocated, until it has been assigned to a global variable (in which case the cleanup functions will handle this). Furthermore, the error messages are always static, so it is not necessary to handle the memory management of that either.)

Post reply on HN