Discussion:
Opinions on `defer`?
Add Reply
Alexis
2025-01-07 00:35:26 UTC
Reply
Permalink
Hi all,

"Modern C" author Jens Gustedt has been posting on his blog about a
proposed `defer` feature (as provided by e.g. Zig and Go), the most
recent being:

https://gustedt.wordpress.com/2025/01/06/simple-defer-ready-to-use/

What do people here think about having such a feature in C?


Alexis.
Kaz Kylheku
2025-01-07 00:53:26 UTC
Reply
Permalink
Post by Alexis
Hi all,
"Modern C" author Jens Gustedt has been posting on his blog about a
proposed `defer` feature (as provided by e.g. Zig and Go), the most
https://gustedt.wordpress.com/2025/01/06/simple-defer-ready-to-use/
What do people here think about having such a feature in C?
I'm okay if a self-hosted implementation can be demonstrated, which
defers itself to a future discussion.
--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @***@mstdn.ca
Thiago Adams
2025-01-08 12:53:07 UTC
Reply
Permalink
Post by Kaz Kylheku
Post by Alexis
Hi all,
"Modern C" author Jens Gustedt has been posting on his blog about a
proposed `defer` feature (as provided by e.g. Zig and Go), the most
https://gustedt.wordpress.com/2025/01/06/simple-defer-ready-to-use/
What do people here think about having such a feature in C?
I'm okay if a self-hosted implementation can be demonstrated, which
defers itself to a future discussion.
There is another proposal
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3199.htm

That is implemented in cake.
http://thradams.com/cake/playground.html



Defer can be useful in some cases, reducing code size, facilitating
maintenance, and centralizing resource release information in one place.

In Cake, ownership qualifiers ensure resources are correctly released,
making it safer than defer and C++ RAII. You don't need to remember to
free resources, as the compiler will warn you if necessary. In this
scenario, defer may still be useful, not for safety, but to reduce the
amount of visible code.
David Brown
2025-01-07 07:49:33 UTC
Reply
Permalink
Post by Alexis
Hi all,
"Modern C" author Jens Gustedt has been posting on his blog about a
proposed `defer` feature (as provided by e.g. Zig and Go), the most
https://gustedt.wordpress.com/2025/01/06/simple-defer-ready-to-use/
What do people here think about having such a feature in C?
I've used gcc's "cleanup" attribute a couple of times, typically in
connection with somewhat messy stuff hidden behind simple macro names.

I think "defer" could be useful on occasion, and could sometimes give
clearer and safer code than "goto"-based error handling. But as with
any such feature there is a risk of abuse - too many "defers" in a
function will make the code as much a spaghetti monster as multiple
goto's. If people use it to keep code neater and reduce the risk of
resource leakage, it can be a good thing. If they use it as an excuse
to write even bigger and more illegible functions, it's bad.
Phillip
2025-01-07 14:53:57 UTC
Reply
Permalink
Post by David Brown
Post by Alexis
Hi all,
"Modern C" author Jens Gustedt has been posting on his blog about a
proposed `defer` feature (as provided by e.g. Zig and Go), the most
   https://gustedt.wordpress.com/2025/01/06/simple-defer-ready-to-use/
What do people here think about having such a feature in C?
I've used gcc's "cleanup" attribute a couple of times, typically in
connection with somewhat messy stuff hidden behind simple macro names.
I think "defer" could be useful on occasion, and could sometimes give
clearer and safer code than "goto"-based error handling.  But as with
any such feature there is a risk of abuse - too many "defers" in a
function will make the code as much a spaghetti monster as multiple
goto's.  If people use it to keep code neater and reduce the risk of
resource leakage, it can be a good thing.  If they use it as an excuse
to write even bigger and more illegible functions, it's bad.
The latter will always be the case. So you have to decide if adding this
is worth the abuse it WILL get. Any ideas that this won't be abused is
just naive. The abuse will get worse as time goes on.
--
Phillip Frabott
----------
- Adam: Is a void really a void if it returns?
- Jack: No, it's just nullspace at that point.
----------
John McCue
2025-01-07 15:50:52 UTC
Reply
Permalink
Alexis <***@gmail.com> wrote:
<snip>
Post by Alexis
https://gustedt.wordpress.com/2025/01/06/simple-defer-ready-to-use/
What do people here think about having such a feature in C?
Interesting, but I really do not have an opinion on this.
Personally, I would not have a need to use & glad it was
implemented via a define.
--
[t]csh(1) - "An elegant shell, for a more... civilized age."
- Paraphrasing Star Wars
Bonita Montero
2025-01-07 18:17:51 UTC
Reply
Permalink
Post by Alexis
Hi all,
"Modern C" author Jens Gustedt has been posting on his blog about a
proposed `defer` feature (as provided by e.g. Zig and Go), the most
https://gustedt.wordpress.com/2025/01/06/simple-defer-ready-to-use/
What do people here think about having such a feature in C?
That doesn’t save this hopelessly outdated programming language either.

When I dont't have a RAII-class for a special purpose in C++ I use my
class invoke_on_destruct:

#pragma once
#include <utility>

template<typename Fn>
struct invoke_on_destruct;

struct iod_base
{
private:
template<typename Fn>
friend struct invoke_on_destruct;
bool m_enabled;
iod_base *m_next;
iod_base( iod_base *next ) :
m_enabled( true ),
m_next( next )
{
}
iod_base( iod_base const & ) = default;
iod_base( iod_base && ) = default;
void disable()
{
m_enabled = false;
}
};

template<typename Fn>
struct invoke_on_destruct final : public iod_base
{
private:
Fn m_fn;
public:
invoke_on_destruct( Fn &&fn, iod_base *next = nullptr )
requires requires( Fn fn ) { { fn() }; } :
iod_base( next ),
m_fn( std::forward<Fn>( fn ) )
{
}
invoke_on_destruct( invoke_on_destruct const & ) = default;
invoke_on_destruct( invoke_on_destruct && ) = default;
~invoke_on_destruct()
{
bool enabled = m_enabled;
if( m_next )
m_next->m_enabled = enabled;
if( enabled )
m_fn();
}
void operator ()()
{
m_enabled = false;
m_fn();
}
using iod_base::disable;
};

Simply use like that;

void *p = ...
invoke_on_destruct iod( [&] { deallocate( p ); } );
Chris M. Thomasson
2025-01-08 22:39:07 UTC
Reply
Permalink
Post by Bonita Montero
Post by Alexis
Hi all,
"Modern C" author Jens Gustedt has been posting on his blog about a
proposed `defer` feature (as provided by e.g. Zig and Go), the most
   https://gustedt.wordpress.com/2025/01/06/simple-defer-ready-to-use/
What do people here think about having such a feature in C?
That doesn’t save this hopelessly outdated programming language either.
When I dont't have a RAII-class for a special purpose in C++ I use my
[...]

Reminds me of ScopeGuard. ;^)
Bonita Montero
2025-01-09 07:24:29 UTC
Reply
Permalink
Post by Chris M. Thomasson
Reminds me of ScopeGuard. ;^)
But better than this. If you have multiple changes on a data structure
and the last fails the invoke_on_destruct-s are chained and revert the
changes incrementally.
Bonita Montero
2025-01-11 14:46:41 UTC
Reply
Permalink
Post by Bonita Montero
Post by Chris M. Thomasson
Reminds me of ScopeGuard. ;^)
But better than this. If you have multiple changes on a data structure
and the last fails the invoke_on_destruct-s are chained and revert the
changes incrementally.
I optimized the whole thing now a bit. Now I have two classed called
defer and xdefer. defer isn't chainable and xdefer is chainable.

#pragma once
#include <utility>
#include <concepts>

template<std::invocable Fn>
struct defer final
{
defer( Fn &&fn ) :
m_enabled( true ),
m_fn( std::forward<Fn>( fn ) )
{
}
defer( defer const & ) = delete;
~defer()
{
if( m_enabled ) [[likely]]
m_fn();
}
void operator ()()
{
if( !m_enabled ) [[unlikely]]
return;
m_fn();
m_enabled = false;
}
void disable()
{
m_enabled = false;
}
private:
bool m_enabled;
#if defined(_MSC_VER)
[[msvc::no_unique_address]]
#else
[[no_unique_address]]
#endif
Fn m_fn;
};

template<std::invocable Fn, std::invocable FnNext = Fn>
struct xdefer final
{
xdefer( Fn &&fn, xdefer<FnNext> *next = nullptr ) :
m_enabled( true ),
m_next( next ),
m_fn( std::forward<Fn>( fn ) )
{
}
xdefer( xdefer const & ) = delete;
~xdefer()
{
bool enabled = m_enabled;
if( m_next ) [[likely]]
m_next->m_enabled = enabled;
if( enabled ) [[likely]]
m_fn();
}
void operator ()()
{
if( !m_enabled ) [[unlikely]]
return;
m_fn();
m_enabled = false;
if( !m_next ) [[likely]]
return;
m_next->m_enabled = true;
(*m_next)();
}
void disable()
{
m_enabled = false;
}
private:
template<std::invocable Fn1, std::invocable Fn2>
friend struct xdefer;
bool m_enabled;
xdefer<FnNext> *m_next;
#if defined(_MSC_VER)
[[msvc::no_unique_address]]
#else
[[no_unique_address]]
#endif
Fn m_fn;
};
Janis Papanagnou
2025-01-08 00:21:08 UTC
Reply
Permalink
Post by Alexis
Hi all,
"Modern C" author Jens Gustedt has been posting on his blog about a
proposed `defer` feature (as provided by e.g. Zig and Go), the most
https://gustedt.wordpress.com/2025/01/06/simple-defer-ready-to-use/
What do people here think about having such a feature in C?
(For C++, as the author also intended, it seems, IME, to not make much
sense.) For "C", inspecting the samples on that page, the most obvious
application case seems to me to be the heap allocations; there I first
had the question of how it would behave e.g. with 'realloc's. But more
importantly, it doesn't seem to match my typical applications of heap
allocations, which I regularly don't do with just a block scope - on
block scope I prefer stack allocations. Using heap objects I typically
pass the pointers across function call boundaries. So it doesn't seem
to be useful to me if the 'defer' feature controls just block scopes.
(And if, in a future version, it would control wider scopes then I'd
fear we'd just get a re-iteration of something like C-with-classes and
then C++.) Assuming that I'd want some 'defer' functionality I'd rather
use C++ instead (where I can use native C++ features for such) instead
a "new C [with 'defer']" release.

(BTW; I don't see any "abuse" potential with 'defer', as suggested in
other posts. Just little gain for few special cases.)

Janis
Kaz Kylheku
2025-01-08 01:02:05 UTC
Reply
Permalink
Post by Janis Papanagnou
Post by Alexis
Hi all,
"Modern C" author Jens Gustedt has been posting on his blog about a
proposed `defer` feature (as provided by e.g. Zig and Go), the most
https://gustedt.wordpress.com/2025/01/06/simple-defer-ready-to-use/
What do people here think about having such a feature in C?
(For C++, as the author also intended, it seems, IME, to not make much
sense.) For "C", inspecting the samples on that page, the most obvious
application case seems to me to be the heap allocations; there I first
had the question of how it would behave e.g. with 'realloc's. But more
importantly, it doesn't seem to match my typical applications of heap
allocations, which I regularly don't do with just a block scope - on
If you do anything like this:

FILE *f = fopen(...);

if (f) {
/* read file */
fclose(f);
} else {
/* error */
}

you have heap allocation in a block scope discipline. You can't make
that a stack allocation, because there is no such thing as this:

FILE fobj;
FILE *f = fopen_fobj(&fobj, ...);

and even if there were such a thing, you'd still need to call a
destructor similar to fclose it to close the file descriptor inside
fobj and free any dynamic buffers!

Defer could be used to help manage home-grown exception handling.
In home-grown exception handling schemes, you push your own unwind
info. This is hidden by macros:

{
unwind_frame_t uf;
exception_push_frame(&uf);

...

exception_pop_frame(&uf);
}

If you leave that scope, forgetting to pop, it's a big problem.
A defer mechanism could help with that.
--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @***@mstdn.ca
BlueManedHawk
2025-01-08 14:14:31 UTC
Reply
Permalink
No.
Tim Rentsch
2025-01-08 19:30:24 UTC
Reply
Permalink
Post by Alexis
Hi all,
"Modern C" author Jens Gustedt has been posting on his blog about a
proposed `defer` feature (as provided by e.g. Zig and Go), the most
https://gustedt.wordpress.com/2025/01/06/simple-defer-ready-to-use/
What do people here think about having such a feature in C?
The issue being addressed is one well worth addressing.

The proposed solution ('defer') is awful. If this feature is
being considered for the C standard it should be rejected
out of hand.
Thiago Adams
2025-01-08 20:25:46 UTC
Reply
Permalink
Post by Tim Rentsch
Post by Alexis
Hi all,
"Modern C" author Jens Gustedt has been posting on his blog about a
proposed `defer` feature (as provided by e.g. Zig and Go), the most
https://gustedt.wordpress.com/2025/01/06/simple-defer-ready-to-use/
What do people here think about having such a feature in C?
The issue being addressed is one well worth addressing.
What is the issue in your opinion?
Post by Tim Rentsch
The proposed solution ('defer') is awful. If this feature is
being considered for the C standard it should be rejected
out of hand.
Why?

I will tell what is the issue it solves in my opinion.
If you don't have static analysis to guide you on where to free
resources, defer helps prevent human error by ensuring resources are
released properly. With defer, you only need to specify the cleanup in
one place, reducing the chances of forgetting it elsewhere. This makes
the code easier to maintain.

However, I think this problem is better addressed with static analysis,
which provides stronger safety guarantees.(This is what I have done in
Cake, with static analysis)

If there's a better solution, is defer unnecessary?

I think defer still useful to write less code, to add the same
information in just one place.

Sample:

{
FILE * f = fopen(...);
if (f == null) return 1;
defer fclose(f);
...
more code..
...
}
Thiago Adams
2025-01-08 20:30:53 UTC
Reply
Permalink
Post by Thiago Adams
Post by Tim Rentsch
Post by Alexis
Hi all,
"Modern C" author Jens Gustedt has been posting on his blog about a
proposed `defer` feature (as provided by e.g. Zig and Go), the most
   https://gustedt.wordpress.com/2025/01/06/simple-defer-ready-to-use/
What do people here think about having such a feature in C?
The issue being addressed is one well worth addressing.
What is the issue in your opinion?
Post by Tim Rentsch
The proposed solution ('defer') is awful.  If this feature is
being considered for the C standard it should be rejected
out of hand.
Why?
I will tell what is the issue it solves in my opinion.
If you don't have static analysis to guide you on where to free
resources, defer helps prevent human error by ensuring resources are
released properly. With defer, you only need to specify the cleanup in
one place, reducing the chances of forgetting it elsewhere. This makes
the code easier to maintain.
However, I think this problem is better addressed with static analysis,
which provides stronger safety guarantees.(This is what I have done in
Cake, with static analysis)
If there's a better solution, is defer unnecessary?
I think defer still useful to write less code, to add the same
information in just one place.
Forgot to say...

I think defer can complement static analysis. Even if static analysis
improves, the two features are not in conflict; they can work together.
The evolution of static analysis won't compete with defer; otherwise, I
would simply say, 'Hold off', because a better solution would be coming
in the future.
David Brown
2025-01-09 13:01:48 UTC
Reply
Permalink
Post by Tim Rentsch
Post by Alexis
Hi all,
"Modern C" author Jens Gustedt has been posting on his blog about a
proposed `defer` feature (as provided by e.g. Zig and Go), the most
https://gustedt.wordpress.com/2025/01/06/simple-defer-ready-to-use/
What do people here think about having such a feature in C?
The issue being addressed is one well worth addressing.
The proposed solution ('defer') is awful. If this feature is
being considered for the C standard it should be rejected
out of hand.
Jens Gustedt is not just some random C programmer - or even just some
random C book author. He is an active member of the C standards
committee, AFAIUI.

You might not agree with his suggested feature, and perhaps the rest of
the C standards committee will reject it - that's why there is a
committee, so that different ideas and suggestions can be discussed and
considered from different viewpoints.

But his suggestion should /not/ be rejected out of hand. The guy has
the qualifications, and done the work, to have the right to be given
serious consideration. If the committee read the proposal, consider it,
then reject it, then that's fair enough.

You, on the other hand, can proudly boast the qualification "random guy
off the internet with strong opinions" - like most of us here. When you
give an opinion with no justification or reasoning, /that/ opinion can
be rejected out of hand.

Give some reasons why you think it is so awful, and why you think your
arguments trump those of Jens Gustedt.
Kaz Kylheku
2025-01-09 19:40:23 UTC
Reply
Permalink
Post by David Brown
Post by Tim Rentsch
Post by Alexis
Hi all,
"Modern C" author Jens Gustedt has been posting on his blog about a
proposed `defer` feature (as provided by e.g. Zig and Go), the most
https://gustedt.wordpress.com/2025/01/06/simple-defer-ready-to-use/
What do people here think about having such a feature in C?
The issue being addressed is one well worth addressing.
The proposed solution ('defer') is awful. If this feature is
being considered for the C standard it should be rejected
out of hand.
Jens Gustedt is not just some random C programmer - or even just some
random C book author. He is an active member of the C standards
committee, AFAIUI.
You might not agree with his suggested feature, and perhaps the rest of
the C standards committee will reject it - that's why there is a
committee, so that different ideas and suggestions can be discussed and
considered from different viewpoints.
But his suggestion should /not/ be rejected out of hand. The guy has
the qualifications, and done the work, to have the right to be given
He has written a few macros relying on GCC features, where the real work
has been done.

That underlying GCC features is what should be standardized, if anything,
and not the proposed defer syntax:

- nested functions which have access to the parent lexicals
- the cleanup feature
- the __COUNTER__ preprocessor feature

All of these are beyond proof-of-concept, but used in production. It is
years old and mature.

What we don't want is ISO C to be reinventing any more GCC extensions,
in a different way. There is an annoying history of that.
(It's bad enough when committees just invent stuff that hasn't been
implemented anywhere, but it's almost an insult when they ignore what
has been implemented and invent something incompatible.)

Note: the nested, local functions used in the presented solution are not
being used as downward funargs (functional arguments): i.e. passed down
to callee functions for indirect calling. The cleanup calls take place
in the parent function frame. Thus for the purposes of these defer
macros, we don't need to specify a full blown nested function that
supports downward funargs. The standard could say that if the address
of a local function is communicated outside of the function scope where
it was taken, its value is indeterminate. Then the downard funarg
support becomes a GNU extension.

Supporting downward funargs is not a mere difficulty. The solution
chosen in GCC for local access (trampolines) has security implications:
a program which uses local functions (such as one relying on these defer
macros) requires an executable stack: the virtual memory pages of its
stack segment allow code execution. This is because pointers to local
functions are aimed at small pieces of dynamically generated machine
code, allocated on the stack, called trampolines. A trampoline is
co-located with the environment pointer needed by the closure; its tiny
machine code sequence loads the environment pointer relative to the
program counter, and then calls the real function (which is not stack
allocated). Thus, a function-with-environment which would normally
require two pointer-sized words of storage can be represented by a
simple function pointer.
--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @***@mstdn.ca
David Brown
2025-01-09 20:31:35 UTC
Reply
Permalink
Post by Kaz Kylheku
Post by David Brown
Post by Tim Rentsch
Post by Alexis
Hi all,
"Modern C" author Jens Gustedt has been posting on his blog about a
proposed `defer` feature (as provided by e.g. Zig and Go), the most
https://gustedt.wordpress.com/2025/01/06/simple-defer-ready-to-use/
What do people here think about having such a feature in C?
The issue being addressed is one well worth addressing.
The proposed solution ('defer') is awful. If this feature is
being considered for the C standard it should be rejected
out of hand.
Jens Gustedt is not just some random C programmer - or even just some
random C book author. He is an active member of the C standards
committee, AFAIUI.
You might not agree with his suggested feature, and perhaps the rest of
the C standards committee will reject it - that's why there is a
committee, so that different ideas and suggestions can be discussed and
considered from different viewpoints.
But his suggestion should /not/ be rejected out of hand. The guy has
the qualifications, and done the work, to have the right to be given
He has written a few macros relying on GCC features, where the real work
has been done.
That underlying GCC features is what should be standardized, if anything,
- nested functions which have access to the parent lexicals
- the cleanup feature
- the __COUNTER__ preprocessor feature
All of these are beyond proof-of-concept, but used in production. It is
years old and mature.
Yes, standardising these would be a good thing for C IMHO. (I seem to
recall __COUNTER__ being standardised, but I'm not sure on that.) I
believe Jens Gustedt has also proposed a form of lambdas for C - that
would work as an alternative to gcc's nested functions.

However such local functions end up if and when they get standardised, I
think it is not unreasonable if there are restrictions that block any
usage that requires passing around data in addition to the function.
That is to say, you should not be able to pass on a pointer to a local
function that has captures - anything that needs a gcc nested function
"trampoline" or a C++ lambda style function object should not be
allowed. That would still leave full flexibility for local use of local
functions - such as used here for the "defer" macros - as well as
supporting convenient local functions for things like qsort comparison
functions.
Post by Kaz Kylheku
What we don't want is ISO C to be reinventing any more GCC extensions,
in a different way. There is an annoying history of that.
Sometimes they do need to make some modifications to gcc extensions -
but it is nice when they don't need to.
Post by Kaz Kylheku
(It's bad enough when committees just invent stuff that hasn't been
implemented anywhere, but it's almost an insult when they ignore what
has been implemented and invent something incompatible.)
I don't think they now accept any serious change that hasn't been tested
in a real implementation.
Post by Kaz Kylheku
Note: the nested, local functions used in the presented solution are not
being used as downward funargs (functional arguments): i.e. passed down
to callee functions for indirect calling. The cleanup calls take place
in the parent function frame. Thus for the purposes of these defer
macros, we don't need to specify a full blown nested function that
supports downward funargs. The standard could say that if the address
of a local function is communicated outside of the function scope where
it was taken, its value is indeterminate. Then the downard funarg
support becomes a GNU extension.
Agreed (though I'd also be happy to accept passing on a local function's
address if it is self-contained and does not access any captures).

(I should have read the rest of your post before writing much the same
thing a few paragraphs up, as it covers much the same thing.)
Post by Kaz Kylheku
Supporting downward funargs is not a mere difficulty. The solution
a program which uses local functions (such as one relying on these defer
macros) requires an executable stack: the virtual memory pages of its
stack segment allow code execution. This is because pointers to local
functions are aimed at small pieces of dynamically generated machine
code, allocated on the stack, called trampolines. A trampoline is
co-located with the environment pointer needed by the closure; its tiny
machine code sequence loads the environment pointer relative to the
program counter, and then calls the real function (which is not stack
allocated). Thus, a function-with-environment which would normally
require two pointer-sized words of storage can be represented by a
simple function pointer.
Michael S
2025-01-09 20:40:24 UTC
Reply
Permalink
On Thu, 9 Jan 2025 21:31:35 +0100
Post by David Brown
Post by Kaz Kylheku
Post by David Brown
Post by Tim Rentsch
Post by Alexis
Hi all,
"Modern C" author Jens Gustedt has been posting on his blog
about a proposed `defer` feature (as provided by e.g. Zig and
https://gustedt.wordpress.com/2025/01/06/simple-defer-ready-to-use/
What do people here think about having such a feature in C?
The issue being addressed is one well worth addressing.
The proposed solution ('defer') is awful. If this feature is
being considered for the C standard it should be rejected
out of hand.
Jens Gustedt is not just some random C programmer - or even just
some random C book author. He is an active member of the C
standards committee, AFAIUI.
You might not agree with his suggested feature, and perhaps the
rest of the C standards committee will reject it - that's why
there is a committee, so that different ideas and suggestions can
be discussed and considered from different viewpoints.
But his suggestion should /not/ be rejected out of hand. The guy
has the qualifications, and done the work, to have the right to be
given
He has written a few macros relying on GCC features, where the real
work has been done.
That underlying GCC features is what should be standardized, if
- nested functions which have access to the parent lexicals
- the cleanup feature
- the __COUNTER__ preprocessor feature
All of these are beyond proof-of-concept, but used in production.
It is years old and mature.
Yes, standardising these would be a good thing for C IMHO. (I seem
to recall __COUNTER__ being standardised, but I'm not sure on that.)
I believe Jens Gustedt has also proposed a form of lambdas for C -
that would work as an alternative to gcc's nested functions.
However such local functions end up if and when they get
standardised, I think it is not unreasonable if there are
restrictions that block any usage that requires passing around data
in addition to the function. That is to say, you should not be able
to pass on a pointer to a local function that has captures - anything
that needs a gcc nested function "trampoline" or a C++ lambda style
function object should not be allowed. That would still leave full
flexibility for local use of local functions -
I'd rather not open this particular can of worms (or is it Pandora
box?). The only good local function is the one that don't exist
Post by David Brown
such as used here for
the "defer" macros - as well as supporting convenient local functions
for things like qsort comparison functions.
qsort is helpless regardless. Stick a fork in it.
Bonita Montero
2025-01-09 15:40:29 UTC
Reply
Permalink
The proposed solution ('defer') is awful. ...
Why ?
Scott Lurndal
2025-01-09 16:41:42 UTC
Reply
Permalink
The proposed solution ('defer') is awful. ...
Why ?
If you want destructors, use c++.
Bonita Montero
2025-01-09 17:42:18 UTC
Reply
Permalink
Post by Scott Lurndal
Why ?
If you want destructors, use c++.
If you're stuck with plain C, something like defer would
be a huge relief over gotos as used in the Linux kernel.
Scott Lurndal
2025-01-09 18:23:46 UTC
Reply
Permalink
Post by Bonita Montero
Post by Scott Lurndal
Why ?
If you want destructors, use c++.
If you're stuck with plain C, something like defer would
be a huge relief over gotos as used in the Linux kernel.
Most C-code can be compiled with a C++ compiler, and
one can selectively use certain C++ features, such as
destructors.

I don't find the 'defer' proposal readable and I suspect it
may lead to more maintainability issues that simple gotos.
Bonita Montero
2025-01-10 14:05:27 UTC
Reply
Permalink
Post by Scott Lurndal
I don't find the 'defer' proposal readable and I suspect it
may lead to more maintainability issues that simple gotos.
It has the same readability like a scope_guard.
Scott Lurndal
2025-01-10 15:06:05 UTC
Reply
Permalink
Post by Bonita Montero
Post by Scott Lurndal
I don't find the 'defer' proposal readable and I suspect it
may lead to more maintainability issues that simple gotos.
It has the same readability like a scope_guard.
Thank you for making my point.
Bonita Montero
2025-01-11 12:03:12 UTC
Reply
Permalink
Post by Scott Lurndal
Post by Bonita Montero
Post by Scott Lurndal
I don't find the 'defer' proposal readable and I suspect it
may lead to more maintainability issues that simple gotos.
It has the same readability like a scope_guard.
Thank you for making my point.
A scope-guard isn't badly readable.
David Brown
2025-01-10 18:13:16 UTC
Reply
Permalink
Post by Scott Lurndal
Post by Bonita Montero
Post by Scott Lurndal
Why ?
If you want destructors, use c++.
If you're stuck with plain C, something like defer would
be a huge relief over gotos as used in the Linux kernel.
Most C-code can be compiled with a C++ compiler, and
one can selectively use certain C++ features, such as
destructors.
I don't find the 'defer' proposal readable and I suspect it
may lead to more maintainability issues that simple gotos.
A new feature - or "advanced" macro (as distinct from a little
function-like macro or a literal or constant value) - will always have
maintainability issues as developers will be unfamiliar with it.

But a big potential benefit from a "defer" feature (or scope-guard
template in C++) comes when replacing /complicated/ gotos, not simple ones.
Tim Rentsch
2025-01-13 14:47:58 UTC
Reply
Permalink
Post by Bonita Montero
Post by Scott Lurndal
Why ?
If you want destructors, use c++.
If you're stuck with plain C, something like defer would
be a huge relief over gotos as used in the Linux kernel.
Most C-code can be compiled with a C++ compiler, [...]
That used to be true. These days the two languages have
diverged enough so that it is no longer a good assumption.
I don't find the 'defer' proposal readable and I suspect it
may lead to more maintainability issues that simple gotos.
Instead of calling it 'defer' it should be called 'goto++'.
Bonita Montero
2025-01-13 18:59:27 UTC
Reply
Permalink
Post by Tim Rentsch
Post by Scott Lurndal
I don't find the 'defer' proposal readable and I suspect it
may lead to more maintainability issues that simple gotos.
Instead of calling it 'defer' it should be called 'goto++'.
C is a such rudimentary language that I don't have problems
with gotos for that, but defer would be a nice addition.

Loading...