upvote
> returning 2 values

> act on context structures

Same semantics but mutating context is much harder to track, so yes it is preferred to return 2 values.

reply
So, returning 2 values is more performant than returning 1.

How does this affect branch prediction ?

When code is structued:

  ...

  result = function1(arg1,arg2,etc);
  if ( !result ) handle_error(result);

  result = function2(arg1,arg2,etc);
  if ( !result ) handle_error(result);

  ...
branch prediction performs well.

I guess if you're checking and branching on 2 values, it performs twice as well ?

reply
Returning 2 values can be more performant than returning one and assigning to another as an "out parameter".

Eg:

    typedef struct {
        bool has_value;
        int value;
    } option_int_t;

    option_int_t foo() {
        if (somecond) return (option_int_t){ true, somevalue };
        else return (option_int_t){ false };
    }
  
    bool bar(int *out) {
        if (somecond) {
            *out = somevalue;
            return true;
        }
        return false;
    }
`foo` is slightly more efficient than `bar` on 64-bit SYSV, whose ABI supports 128-bit ("two eightbytes") returns in hardware registers. `bar` requires at least one dereference to assign the result.

On other compilers this isn't the case. MSVC only supports 64-bit returns and would use the stack for `option_int_t`. The caller allocates the space and an implicit pointer is passed in the first argument register (eg, `rcx`), and the same pointer is returned as the result.

reply