> act on context structures
Same semantics but mutating context is much harder to track, so yes it is preferred to return 2 values.
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 ?
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.