On Fri, Apr 16, 2021 at 03:34:50PM -0500, Connor Kuehl wrote:
> On 4/16/21 3:22 PM, Willy Tarreau wrote:
> > So it simply does the equivalent of:
> > 
> >   #define EINVAL -1234
> > 
> >   struct result {
> >      int status;
> >      int error;
> >   };
> 
> Result and Option types are more like a union with a tag that
> describes which variant it is.
> 
> struct foo_result {
>     /* if ok, then access foo_or_err.successful_foo
>      *        else, access foo_or_err.error
>      */
>     bool ok;
>     union {
>         struct foo successful_foo;
>         int error;
>     } foo_or_err;
> };

OK.

> > [..]
> > 
> > So it simply returns a pair of values instead of a single one, which
> 
> It will only return 1 value.

No, two:
  - ok in %rax (seems like it's "!ok" technically speaking since it
    returns 1 on !ok and 0 on ok)
  - foo_or_err in %rdx

However then I'm bothered because Miguel's example showed that regardless
of OK, EINVAL was always returned in foo_or_err, so maybe it's just
because his example was not well chosen but it wasn't very visible from
the source:

     bar:
             push    rbx
             mov     ebx, 1
             call    qword ptr [rip + black_box@GOTPCREL]
             test    al, al
             jne     .LBB2_2
             call    qword ptr [rip + kill_foo@GOTPCREL]
             xor     ebx, ebx
     .LBB2_2:
             mov     eax, ebx
             mov     edx, -1234
             pop     rbx
             ret

Willy

Reply via email to