From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [IPv6:2a00:1450:4864:20::42c]) by sourceware.org (Postfix) with ESMTPS id AF5923858D28 for ; Sun, 10 Oct 2021 19:24:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org AF5923858D28 Received: by mail-wr1-x42c.google.com with SMTP id r18so48720981wrg.6 for ; Sun, 10 Oct 2021 12:24:57 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:subject:from:to:date:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=RPfc680kcWmAcKtqbCQYV4KEBdvm530uVh2nw3wewe4=; b=GY14n1rtQdQdXTDcZlzB8FhhF06XwZwrA0iMG5XxP9UMJ/owc2augFuzm0RY7csLhy /AsY8XTW6kTpGzQ+evZUwZgF7h56TjKAMpb94FsVw3OJOp5CX0ssICY0YRWgAabEsdFJ KhNM16mMt9hx6Jnew7K662CPxap5kal710/E6Tx/wM7bnOE5cHPjAE2NofvADEISgWPa KnvOg9VE/QewB9+0nvFYMkSQJiHT4omQI3M7mEETOA9afKCaZj2sb5VhclnG3GaRl7UB bYviUl5vmqV3v4YOLFv/eKIk5bCUstSfaKdT1XqQkLnWvnoCOj0S5L5zBZf01tuajQMk 0tqw== X-Gm-Message-State: AOAM5308n3EjYm5Ik8F+Qq636YNy/+TFg5dJ5KcjWmf+c2Rm1BAfaQ8l nliEK4Y6aoT0PGFoHFWxSJk= X-Google-Smtp-Source: ABdhPJxZxF5ab8GlqWNnQ3lApga+sqga4v5mSGQt8xUV48yolyYCBoyj4QmpIiJuUOP1ArvwlkAPdg== X-Received: by 2002:a7b:cf07:: with SMTP id l7mr16926330wmg.10.1633893896348; Sun, 10 Oct 2021 12:24:56 -0700 (PDT) Received: from 2a02-8388-e205-e880-569c-680a-c69b-a1ad.cable.dynamic.v6.surfer.at (2a02-8388-e205-e880-569c-680a-c69b-a1ad.cable.dynamic.v6.surfer.at. [2a02:8388:e205:e880:569c:680a:c69b:a1ad]) by smtp.gmail.com with ESMTPSA id k27sm877850wms.21.2021.10.10.12.24.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 10 Oct 2021 12:24:56 -0700 (PDT) Message-ID: <929290fbe61674eae18dbc7736fa5bf36755e907.camel@gmail.com> Subject: Re: wide function pointer type From: Martin Uecker To: Daniel Colascione , "Kaz Kylheku (libffi)" <382-725-6798@kylheku.com>, Martin Uecker via Libffi-discuss Date: Sun, 10 Oct 2021 21:24:54 +0200 In-Reply-To: <17c6b915c88.283a.cc5b3318d7e9908e2c46732289705cb0@dancol.org> References: <09d27268d43fc4a8885695eba840faa4@mail.kylheku.com> <54e81ff3a4a6569798ba879c47392d4b19ec599b.camel@gmail.com> <17c6b52d0d0.283a.cc5b3318d7e9908e2c46732289705cb0@dancol.org> <742651c57616f676aea2ee8b4a05b24a23cbf974.camel@gmail.com> <17c6b6c63b0.283a.cc5b3318d7e9908e2c46732289705cb0@dancol.org> <7e6bdb9ddd6add840ec46a9069722f27c162d273.camel@gmail.com> <17c6b915c88.283a.cc5b3318d7e9908e2c46732289705cb0@dancol.org> Content-Type: text/plain; charset="UTF-8" User-Agent: Evolution 3.30.5-1.1 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-1.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libffi-discuss@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libffi-discuss mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Oct 2021 19:24:59 -0000 Am Sonntag, den 10.10.2021, 11:57 -0700 schrieb Daniel Colascione: > > On October 10, 2021 11:47:18 Martin Uecker wrote: > > > Am Sonntag, den 10.10.2021, 11:17 -0700 schrieb Daniel Colascione: > > > On October 10, 2021 11:05:07 Martin Uecker wrote: > > > > > > > Am Sonntag, den 10.10.2021, 10:49 -0700 schrieb Daniel Colascione: > > > > > On October 10, 2021 10:44:32 Martin Uecker via Libffi-discuss > > > > > wrote: > > > > > > > > > > > Am Sonntag, den 10.10.2021, 10:01 -0700 schrieb Kaz Kylheku (libffi): > > > > > > > On 2021-10-10 04:32, Martin Uecker via Libffi-discuss wrote: > > > > > > > > Hi all, > > > > > > > > > > > > > > > > I will propose a wide function pointer type (actually > > > > > > > > a wide function type) to WG14 for C23 as a common > > > > > > > > type for callbacks, closures, which now require an > > > > > > > > additional void pointer argument in C APIs. This > > > > > > > > is intended to be compatible with ABIs with now > > > > > > > > use a static chain register. > > > > > > > > > > > > > > Opposed. There is nothing wrong with separate arguments > > > > > > > for function pointer and context. > > > > > > > > > > > > Noted. Your argument sbelow all boil down to the point > > > > > > that there are cases where it might not be the ideal > > > > > > choice. But nobody forces anyone to use it. > > > > > "I like it" is not by itself a rationale for including something in a core > > > > > language standard. This is not something that should be in C. Why, > > > > > precisely, can't you just define a struct with two fields and make that > > > > > your closure type? > > > > > > > > Sure. There are at least five reasons: > > > > > > > > - one now does has to do it manually which is > > > > inconvenient because it has to be done for each type, > > > > although this a common pattern which is trivial > > > > to automate. > > > > > > > > - APIs are often unsafe because they have to use > > > > void pointer to be generic. When the void pointer > > > > can be packaged into the wide pointer this problem > > > > goes away. > > > > > > > > - APIs are often different for no good reason. > > > > Having a standard approach would make this more > > > > canonical, hence simpler and less error prone, > > > > and also more compatible - requiring less adapter > > > > code. > > > > > > > > - There are APIs where a pointer to a > > > > function is expected but there is no data pointer. > > > > Then other languages have a problem interfacing > > > > with such APIs. (or why does libffi generate > > > > trampolines?) > > > > > > > > - Finally, C might get lambda expressions > > > > which are far more useful with such a pointer type. > > > > (for nested function you could avoid executable > > > > stack). > > > > > > > > > > > > All five are good reasons to put a standard > > > > approach in the core language in my opinion. > > > > > > > > > > > > But I am actually not interested in this discussion > > > > and do not have time for it. > > > > > > > > I am more interested in constructive technical > > > > feedback. > > > > > > Your proposal doesn't actually solve any of these problems though, and as > > > we agree, users can already trivially make their own closure types. > > > > I wonder why you think it does not address > > these problems? > > Because there's no difference between your proposal and a simple user > struct that does the same thing. I see at least the following differences: - Simple user code does not know how to load the static chain pointer into its ABI-specified register in a portable way. - A simple user struct works exactly for one function type, so such a struct has to be created for all APIs separately. - One can not easily convert a regular pointer to a simple user struct (this would require at least inserting a branch at it each call site) - A simple user struct can be defined in different ways, so there is no standard. - If a library defines a simple struct and another library another simple struct, then these two structs are not compatible even if defined identically. - Other languages or interface generating tools will not know about the simple user struct, but will certainly know about a standardized type. > The language could get lambdas one day > (though I doubt it), but if it does, each lambda will likely have a unique > and anonymous type (like in C++) and won't fit in your wide function > pointer struct anyway. I think the lambda proposal has a good chance, although I am not sure it will make it already into C23. There would be a conversion rule (as mentioned in the proposal). C++ has std::function for a similar purpose. > > > What *would* be interesting is a new standard library facility for making > > > libffi-style closures and a standard struct type for packaging the things. > > > *That's* something that could be justified for inclusion in a standard > > > library, since it's not something that programs can make on their own > > > without the kind of platform specific glue that libffi provides. > > > > I also would love to have this, but see below... > > > > > Basically, > > > the interface would look something like this: > > > > > > typedef opaque_mumble stdclosure_t; > > > > > > // Returns a callable function pointer or NULL on error with errno set > > > void* stdclosure_init(stdclosure_t* closure, void* fnptr, void* data); > > > > A void* might not be big enough for a callable function > > pointer an all architectures supported by C so this > > needs to return something like > > > > void (*)(); > > > > > > (for POSIX this is not a problem) > > Yeah, although at this point, I'm in favor of standardizing things that are > de facto universal anyway. POSIX for example mandates that NULL is all zero > bits and that function pointers fit in void*, and I think it's time for C > to just acknowledge the same. I tend to agree, but I do not see this happening. > > > > > void stsclosure_destroy(stdclosure_t* closure); > > > > > > The function pointer returned by stdclosure_init would, when called, call > > > FNPTR with an extra initial parameter (or trailing parameter or something) > > > of type void* and value DATA and all the remaining parameters with which it > > > was called. > > > > > > This facility would actually probably have to be more complicated in real > > > life due to varying platform ABIs, but you get the idea. This is something > > > that could belong in the standard because it'd provide a generic > > > abstraction for something every platform can do but that every platform has > > > to do in a slightly different way. > > > > One problem could be that this requires generating > > trampolines at run-time (and it is not clear we > > can do this everywhere where C is supported) or > > having a fixed set of preallocated trampolines. > > Or remapping a fixed set of trampolines, like libffi does on some > platforms. This should be quite expensive though, if you use lots of closures. > The new stdclosure feature would have to be optional, yes, but > in practice it would be supported everywhere people write programs except > maybe a few microcontrollers and DSPs. Yes, you should try to propose this. > > The other limitation (which the new type would > > avoid) is the need for dynamic resource allocation, > > which is sometimes not desirable. > > > > But I would love to see such a proposal > > brought forward. Martin