In early versions of the C language, every function would return something, whether or not the caller would make use of the returned value. Generally, the return value of a function would be whatever happened to be in some particular register of the appropriate type. If code exited a function without making any effort to set the register to something meaningful, and calling code ignored the contents of the register in question, having the function nominally return a meaningless value was simpler and easier than providing a means of having functions not return a value.
I don't think any particular thought was put into the question of what functions like memcpy, strcpy, or strcat should return, but the authors of the Standard didn't want to simply leave the return value unspecified. Since there may have been platforms where functions that don't return a value would be processed differently from those that do, giving such functions a void return type could have broken code that calls the functions without including the appropriate standard header.
I don't think any particular effort was made to have the functions return the most useful value. More likely, the authors of the Standard wanted to have the functions return some specified value, and so they somewhat arbitrarily picked a value to be returned.
strcpy) etc. That just changes the question to “… the rationale for havingstrcpyreturn one of its inputs?” – Stephen Kitt Jun 21 '22 at 14:16void strcpy(char *s, char *t)(no return value) and then just says “Thestrcpyin the standard library (<string.h>) returns the target string as its function value.” – Stephen Kitt Jun 21 '22 at 15:16errnoanderrno.hcan be found here: https://archive.org/details/cprogramming0000koch/page/47/mode/1up – Jim Nelson Jun 21 '22 at 18:02errnois hardly controversial, is it? A global variable to say what error somehow happened once upon a time? Bleurgh. Better use a Rust-styleResulttype. In C you could kinda emulate it with some struct containing either the result of the function call, or an error code. – Omar and Lorraine Jun 23 '22 at 09:10void flip_bits(unsigned short *p) { unsigned t; memcpy(&t, p, 4); t ^= 0xFFFFFFFF; memcpy(p, &t, 4); }into code that uses a 32-bit load and store, the Standard was never intended to imply that programmers jump through such hoops rather than writing code that can be straightforwardly translated into the required machine operations. – supercat Jun 24 '22 at 16:21