• Opinions on `defer`?

    From Alexis@flexibeast@gmail.com to comp.lang.c on Tue Jan 7 11:35:26 2025
    From Newsgroup: comp.lang.c


    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.
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Kaz Kylheku@643-408-1753@kylheku.com to comp.lang.c on Tue Jan 7 00:53:26 2025
    From Newsgroup: comp.lang.c

    On 2025-01-07, Alexis <flexibeast@gmail.com> wrote:

    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?

    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: @Kazinator@mstdn.ca
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Tue Jan 7 08:49:33 2025
    From Newsgroup: comp.lang.c

    On 07/01/2025 01:35, Alexis wrote:

    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?


    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.


    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Phillip@nntp@fulltermprivacy.com to comp.lang.c on Tue Jan 7 09:53:57 2025
    From Newsgroup: comp.lang.c

    On 1/7/25 2:49 AM, David Brown wrote:
    On 07/01/2025 01:35, Alexis wrote:

    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?


    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.
    ----------
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From John McCue@jmccue@neutron.jmcunx.com to comp.lang.c on Tue Jan 7 15:50:52 2025
    From Newsgroup: comp.lang.c

    Alexis <flexibeast@gmail.com> wrote:

    <snip>

    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
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c on Tue Jan 7 19:17:51 2025
    From Newsgroup: comp.lang.c

    Am 07.01.2025 um 01:35 schrieb 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
    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?

    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 ); } );

    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.c on Wed Jan 8 01:21:08 2025
    From Newsgroup: comp.lang.c

    On 07.01.2025 01:35, Alexis wrote:

    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?

    (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

    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Kaz Kylheku@643-408-1753@kylheku.com to comp.lang.c on Wed Jan 8 01:02:05 2025
    From Newsgroup: comp.lang.c

    On 2025-01-08, Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
    On 07.01.2025 01:35, Alexis wrote:

    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?

    (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: @Kazinator@mstdn.ca
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Thiago Adams@thiago.adams@gmail.com to comp.lang.c on Wed Jan 8 09:53:07 2025
    From Newsgroup: comp.lang.c

    On 06/01/2025 21:53, Kaz Kylheku wrote:
    On 2025-01-07, Alexis <flexibeast@gmail.com> wrote:

    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?

    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.







    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From BlueManedHawk@bluemanedhawk@invalid.invalid to comp.lang.c on Wed Jan 8 09:14:31 2025
    From Newsgroup: comp.lang.c

    No.
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Tim Rentsch@tr.17687@z991.linuxsc.com to comp.lang.c on Wed Jan 8 11:30:24 2025
    From Newsgroup: comp.lang.c

    Alexis <flexibeast@gmail.com> writes:

    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?

    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.
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Thiago Adams@thiago.adams@gmail.com to comp.lang.c on Wed Jan 8 17:25:46 2025
    From Newsgroup: comp.lang.c

    On 08/01/2025 16:30, Tim Rentsch wrote:
    Alexis <flexibeast@gmail.com> writes:

    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?

    The issue being addressed is one well worth addressing.


    What is the issue in your opinion?

    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..
    ...
    }






    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Thiago Adams@thiago.adams@gmail.com to comp.lang.c on Wed Jan 8 17:30:53 2025
    From Newsgroup: comp.lang.c

    On 08/01/2025 17:25, Thiago Adams wrote:
    On 08/01/2025 16:30, Tim Rentsch wrote:
    Alexis <flexibeast@gmail.com> writes:

    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?

    The issue being addressed is one well worth addressing.


    What is the issue in your opinion?

    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.




    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Wed Jan 8 14:39:07 2025
    From Newsgroup: comp.lang.c

    On 1/7/2025 10:17 AM, Bonita Montero wrote:
    Am 07.01.2025 um 01:35 schrieb 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
    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?

    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:

    [...]

    Reminds me of ScopeGuard. ;^)
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c on Thu Jan 9 08:24:29 2025
    From Newsgroup: comp.lang.c

    Am 08.01.2025 um 23:39 schrieb 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.

    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Thu Jan 9 14:01:48 2025
    From Newsgroup: comp.lang.c

    On 08/01/2025 20:30, Tim Rentsch wrote:
    Alexis <flexibeast@gmail.com> writes:

    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?

    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.


    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c on Thu Jan 9 16:40:29 2025
    From Newsgroup: comp.lang.c

    Am 08.01.2025 um 20:30 schrieb Tim Rentsch:

    The proposed solution ('defer') is awful. ...

    Why ?
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Thu Jan 9 16:41:42 2025
    From Newsgroup: comp.lang.c

    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 08.01.2025 um 20:30 schrieb Tim Rentsch:

    The proposed solution ('defer') is awful. ...

    Why ?

    If you want destructors, use c++.
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c on Thu Jan 9 18:42:18 2025
    From Newsgroup: comp.lang.c

    Am 09.01.2025 um 17:41 schrieb 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.
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Thu Jan 9 18:23:46 2025
    From Newsgroup: comp.lang.c

    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 09.01.2025 um 17:41 schrieb 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.
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Kaz Kylheku@643-408-1753@kylheku.com to comp.lang.c on Thu Jan 9 19:40:23 2025
    From Newsgroup: comp.lang.c

    On 2025-01-09, David Brown <david.brown@hesbynett.no> wrote:
    On 08/01/2025 20:30, Tim Rentsch wrote:
    Alexis <flexibeast@gmail.com> writes:

    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?

    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: @Kazinator@mstdn.ca
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Thu Jan 9 21:31:35 2025
    From Newsgroup: comp.lang.c

    On 09/01/2025 20:40, Kaz Kylheku wrote:
    On 2025-01-09, David Brown <david.brown@hesbynett.no> wrote:
    On 08/01/2025 20:30, Tim Rentsch wrote:
    Alexis <flexibeast@gmail.com> writes:

    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?

    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.


    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.

    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.

    (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.


    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.)


    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.



    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Michael S@already5chosen@yahoo.com to comp.lang.c on Thu Jan 9 22:40:24 2025
    From Newsgroup: comp.lang.c

    On Thu, 9 Jan 2025 21:31:35 +0100
    David Brown <david.brown@hesbynett.no> wrote:

    On 09/01/2025 20:40, Kaz Kylheku wrote:
    On 2025-01-09, David Brown <david.brown@hesbynett.no> wrote:
    On 08/01/2025 20:30, Tim Rentsch wrote:
    Alexis <flexibeast@gmail.com> writes:

    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?

    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.


    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

    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.


    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c on Fri Jan 10 15:05:27 2025
    From Newsgroup: comp.lang.c

    Am 09.01.2025 um 19:23 schrieb 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.

    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Fri Jan 10 15:06:05 2025
    From Newsgroup: comp.lang.c

    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 09.01.2025 um 19:23 schrieb 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.
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Fri Jan 10 19:13:16 2025
    From Newsgroup: comp.lang.c

    On 09/01/2025 19:23, Scott Lurndal wrote:
    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 09.01.2025 um 17:41 schrieb 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.


    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c on Sat Jan 11 13:03:12 2025
    From Newsgroup: comp.lang.c

    Am 10.01.2025 um 16:06 schrieb Scott Lurndal:
    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 09.01.2025 um 19:23 schrieb 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.

    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c on Sat Jan 11 15:46:41 2025
    From Newsgroup: comp.lang.c

    Am 09.01.2025 um 08:24 schrieb Bonita Montero:
    Am 08.01.2025 um 23:39 schrieb 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;
    };
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Tim Rentsch@tr.17687@z991.linuxsc.com to comp.lang.c on Mon Jan 13 06:47:58 2025
    From Newsgroup: comp.lang.c

    scott@slp53.sl.home (Scott Lurndal) writes:

    Bonita Montero <Bonita.Montero@gmail.com> writes:

    Am 09.01.2025 um 17:41 schrieb 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++'.
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c on Mon Jan 13 19:59:27 2025
    From Newsgroup: comp.lang.c

    Am 13.01.2025 um 15:47 schrieb Tim Rentsch:

    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.
    --- Synchronet 3.20a-Linux NewsLink 1.114