(Sorry, didn't see your answer as I was editing mine. Did some godbolt.org testing.)
I'd love to see ABIs where composite return values could use all the same registers as arguments can. Why not? Their values are currently undefined after return from a function, so there is nothing to be lost.
Me too. I really don't like the C
errno convention; it would be much nicer to just return more than one scalar, so one of them could be the error code (and 0 for no error).
There are quite a few cases like reading from a file or device, where returning some data
and and an error would make the API so much more useful.
Which ties in to this thread nicely: when returning both a numeric value and a pointer, it actually makes sense to pass the pointer as a parameter, and the pointer to the numeric value to be updated, and return the pointer. This is because the code then only does one level of pointer dereferencing.
For example, when parsing (command-line) parameters to a numeric type
NUMTYPE, I use either
int parse_NUMTYPE(const char *from, NUMTYPE *to);returning 0 if success, nonzero errno error code otherwise, if the
from string should be a complete number without any trailing garbage, or
const char *parse_NUMTYPE(const char *from, NUMTYPE *to);returning a pointer to the first unparsed character, or
NULL if there wasn't a number to be parsed.
This might look odd at first, but both the parsing (I usually use strtod()/strtol()/strtoul()/strtoll()/strtoull()) and calling the parsing function is simpler and more robust (maintenance-wise, simpler code) than passing a double pointer.