You and me both. In fact, D does this. `int arr[5]` can be passed as a value argument to a function, and returned as a value argument, just as if it was wrapped in a struct.
It's sad that C (and C++) take every opportunity to instantly decay the array to a pointer, which I've dubbed "C's Biggest Mistake":
To bad they spend most their time doing whatever it is they do.
struct foo { int a[10]; };
struct foo f(void);
int b[10];
b = f().a;
In C90, you can't actually do anything with `f().a` because the conversion from array to pointer only happened to lvalues (`f().a` is not an lvalue), and assignment is not defined for array variables (though gcc allowed it). The meaning is changed in C90 so that non-lvalue arrays are also converted to pointers. gcc used to take this distinction into account, so the above program would compile in C90 mode but not in C99 mode. New versions of gcc seem to forbid array assignment in all cases.I think this quirk also means that it's technically possible to pass actual arrays to variadic functions in C90, since there was nothing to forbid the passing (it worked in gcc at least, though in strict C90, you wouldn't be able to use the non-lvalue array). In C99 and above, a pointer will be passed instead.
Even the few "security" attempts that they have made, still require separate pointer and length arguments, thus voiding any kind of "security" that the functions might try to achieve.
However even a Macro Assembler is safer than modern C compilers, as they don't remove your code when one steps into a UB mine.
sizeof(b.arr) != sizeof(b)
Consider:
#include <stddef.h>
#include <inttypes.h>
typedef struct Array Array;
struct Array {
int32_t data[8];
};
void foo(Array const* arr) {
size_t sz = sizeof(arr->data);
}
[0] http://www.lysator.liu.se/c/bwk-on-pascal.html