public inbox for libffi-discuss@sourceware.org
 help / color / mirror / Atom feed
From: Martin Uecker <ma.uecker@gmail.com>
To: "Kaz Kylheku (libffi)" <382-725-6798@kylheku.com>
Cc: Florian Weimer <fweimer@redhat.com>,
	Martin Uecker via Libffi-discuss <libffi-discuss@sourceware.org>,
	Libffi-discuss
	<libffi-discuss-bounces+382-725-6798=kylheku.com@sourceware.org>
Subject: Re: wide function pointer type
Date: Wed, 20 Oct 2021 20:52:23 +0200	[thread overview]
Message-ID: <dc1111e49609330f82a7b9061ec29d0989372565.camel@gmail.com> (raw)
In-Reply-To: <bfbd97ae6e2466cf12b1760206a69f6e@mail.kylheku.com>

Am Mittwoch, den 20.10.2021, 01:24 -0700 schrieb Kaz Kylheku (libffi):
> On 2021-10-19 05:13, Martin Uecker via Libffi-discuss wrote:
> > void foo(
> >   void (cb1)(void* data, int a), void* data1,
> >   void* other_data);
> > 
> > Here a human (and maybe also a machine) could guess
> > that data1 belongs to cb1 but not other_data.  But
> > it is not clear and in more complicated cases
> > even less so.
> 
> That's a property of almost every C API. You cannot
> guess the properties from the declaration alone.
> 
> If memcpy didn't have the const on the source
> argument, you couldn't guess which argument is
> the destination and which is the source.

The difference here is that something which is a fundamental
type in most other languages is split up into two things
in C.

>                                  y
> Argument names and analogy to x    tell you
> which argument of pow is the base and which the
> exponent.
> 
> That's the job of documentation.

Generators for language wrappers do
not read documentation ;-)

> A declarative mechanism which indicates that a given
> context parameter goes with a given function could
> exist instead of _Wide.

Yes, I had considered this too.

> Such a thing was introduced 22 years ago for VLA's:
> 
>    void fun(int m, double a[m]);

Sure, but VLA types are also underdeveloped
The limitations are:

- You can not store a pointer to a VLA in the struct.
- You can not put the size later.
- You can not
always automatically verify that
the size is correct at the caller side because
the semantic type of a
declaration is:

void fun(int m, double a[*]);

All this would be avoided with a wide
pointer type that integrates the size into the
pointer (as in FORTRAN). This was in fact proposed
by Dennis Ritchie himself a long time ago:

Ritchie DM. Variable-size arrays in C.
The Journal of C Language Translation 1990;2:81-86.

> An obvious convention is possible, and often occurs
> in practice: namely, the context parameter in the API
> function is given a name which exactly matches the
> one in the function pointer:
> 
>    void foo(void (cb1)(void *the_context, int a),
>             void *unrelated_data,
>             void *the_context);
> 
> Your proposal also assumes that closures must always
> be specified as two argument words, which is an
> inappropriate choice to foist onto programmers.

No it does not assume this. You can always keep
doing this as before.

> So that is to say, you're taking it for granted that
> you want to keep a distinct disadvantage of the
> current approach and just wrap it in some syntactic
> sugar machinery so that the two arguments appear
> encapsulated as some _Wide thing passed by value.
> 
> But callback interfaces can easily use just a single
> argument word to point to a object that is passed
> with reference semantics; that object has a function
> and context data.

I am not sure what you are talking about..

> In high level languages with closures, like Lisp
> dialects, closures are of the same "size" as other
> values; e.g. 32 or 64 bit pointer-sized word or
> what have you.
> 
> C++ callback objects are usually one pointer also.
> 
>     void f(CallBackBase *cb)
>     {
>        (*cb)(42); // via operator ()
>        // or
>        cb->callBack(42); // regular member function
>     }

Not at all. C++ has std::function for this purpose
which is usually even bigger than two words because
it does an optimization for small objects.

> C programs do this too:
> 
>     void f(struct obj *o)
>     {
>        o->ops->callback(o, 42);
>     }
> 
> Or with the ops table in the object instance:
> 
>     void f(struct obj *o)
>     {
>        o->ops.callback(o, 42);
>     }
> 
> The idea that all callback interfaces in C
> use a function and a void * argument is a false; you
> have to survey the entire field of practice in this general
> area.

I never claimed that "all callbacks use void*". So please
do not use strawman arguments.

> > void foo(void (_Wide cb1)(int a), void* other_data);
> 
> Without _Wide, we have
> 
>    void (cb1)(int a)
> 
> That (cb1)(int a) is a function declarator (with superfluous
> parentheses); but when that occurs as a parameter, it
> declares a function pointer: it is equivalent to:
> 
>    void (*cb1)(int a)
> 
> But it looks like
> 
>     void (_Wide cb1)(int)
> 
> might not be similarly equivalent to
> 
>     void (_Wide *cb1)(int)
> 
> and the difference could be useful.
>
> Furthermore, given that you can have a _Wide value W, or
> a pointer to a _Wide value PW, do you call them using different
> syntax?
> 
> Is it just W(arg, ...) and PW(arg, ....)?
> 
> Or do we require (*PW)(arg, ...)?
>
> If we don't require it, is it because of a decay rule, so that
> we can write PW(arg, ...) or (*PW)(arg, ...) or (**PW)(arg, ...)?
> and same with W? Or is it due to separately articulated semantics:
> that the function call operator works with a _Wide and a
> pointer-to_Wide, without any "decay" conversion going on?

If _Wide is a qualifier as in the proposal
Function types nothing changes.

Martin





  reply	other threads:[~2021-10-20 18:52 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-10 11:32 Martin Uecker
2021-10-17 23:35 ` Anthony Green
2021-10-18  5:33   ` Martin Uecker
2021-10-18  5:58     ` Martin Uecker
2021-10-18  7:36       ` Florian Weimer
2021-10-18  7:56         ` Martin Uecker
2021-10-19  9:22           ` Florian Weimer
2021-10-19  9:43             ` Martin Uecker
2021-10-19 10:15               ` Florian Weimer
2021-10-19 12:13                 ` Martin Uecker
2021-10-20  8:24                   ` Kaz Kylheku (libffi)
2021-10-20 18:52                     ` Martin Uecker [this message]
2021-10-20  9:10                   ` Florian Weimer
2021-10-20  9:21                     ` Martin Uecker
2021-10-20  9:27                       ` Florian Weimer
2021-10-20 17:27                     ` Kaz Kylheku (libffi)
2021-10-21  9:48                       ` Florian Weimer
2021-10-10 17:01 Kaz Kylheku (libffi)
2021-10-10 17:44 ` Martin Uecker
2021-10-10 17:49   ` Daniel Colascione
2021-10-10 18:05     ` Martin Uecker
2021-10-10 18:17       ` Daniel Colascione
2021-10-10 18:47         ` Martin Uecker
2021-10-10 18:57           ` Daniel Colascione
2021-10-10 19:24             ` Martin Uecker
2021-10-16  8:08               ` Jarkko Hietaniemi
2021-10-16  9:35                 ` Jarkko Hietaniemi
2021-10-10 18:31   ` Kaz Kylheku (libffi)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=dc1111e49609330f82a7b9061ec29d0989372565.camel@gmail.com \
    --to=ma.uecker@gmail.com \
    --cc=382-725-6798@kylheku.com \
    --cc=fweimer@redhat.com \
    --cc=libffi-discuss-bounces+382-725-6798=kylheku.com@sourceware.org \
    --cc=libffi-discuss@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).