Re: Transfer rules of inout parameters

On Fri, Feb 9, 2018 at 3:31 AM Philip Withnall <philip tecnocode co uk> wrote:
On Fri, 2018-02-09 at 07:49 +0000, philip chimento gmail com wrote:
> Next up! (I think this is the last of my Bugzilla-migration-triggered
> mail series.)
> Transfer rules of inout parameters:
> tl;dr: some time ago a commit to gobject-introspection broke a test
> in GJS and I've never been able to figure out whether gobject-
> introspection or GJS is wrong.
> I always thought inout worked like this: a function with an inout
> parameter
> /* inout: (transfer full): */
> void func(char **inout) {
>     g_assert (strcmp (*inout, utf8_const) == 0);
>     g_free (*inout);
>     *inout = g_strdup (utf8_nonconst);
> }
> should have exactly the same transfer rules as a function with two
> separate parameters
> /* in: (transfer full):
>  * out: (transfer full): */
> void func2(char *in, char **out) {
>     g_assert (strcmp (in, utf8_const) == 0);
>     g_free (in);
>     *out = g_strdup (utf8_nonconst);
> }
> That, at least I think, is how gobject-introspection specifies it (de
> facto, by virtue of the code working like that.) GJS interprets it
> as
> in: (transfer none)
> out: (transfer full)
> and Giovanni commented on that bug, that he thought existing
> libraries required that interpretation.
> The test in GJS has been commented out for 2 years waiting for me to
> figure this out. Does anyone know?

I don’t know what the original interpretation was meant to be, but
here’s an off-the-wall idea:
 • Deprecate (inout).
 • Instead, allow separate annotations for the ‘in’ and ‘out’ modes for
a parameter; something like (in (nullable) (transfer none)) (out (not
nullable) (transfer full)).
 • That’s because quite a few of the annotations could theoretically
differ between the modes: nullability, transfer and array length.
 • Because this is tricky to reason about, don’t have a default:
require that everything is always specified for inout parameters.
 • My suggested syntax is horrible.

Alternatively, if an audit of all our inout parameters shows that they
all have (for example) the same nullability and array length for in and
out modes, we could go with something simpler like (inout TRANSFER-IN
TRANSFER-OUT). Any APIs which have more complex inout parameters should
be considered un-introspectable, and would have to be replaced with
another API which splits the inout parameter in two in order to be

I think either of these would be fine, but either way we'd still need to define a default TRANSFER-IN and TRANSFER-OUT for the case where libraries hadn't yet adapted their annotations.

Philip C

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]