There is a technique for passing arrays that do not decay to pointers. You pass the array by reference, using the syntax below. The required "extra" parens are a syntactical wart, and probably why this usage is not more common. One gets used to it real fast, given the advantages.
void sub(double (&foo)[4])
{
cout << sizeof(foo) << endl;
}
Prints 32, not sizeof(double*), because the type of foo really is a reference to an array of 4 doubles. Using templates, you can generalize to work for any size of array:
template <int N> sub(double (&foo)[N])
{
cout << sizeof(foo) << endl;
}
double bar[5];
double zot[3];
sub(bar); // ==> 40
sub(zot); // ==> 24
You can generalize again to handle an any-size array of anything:
template <class T, int N>void sub(T(&foo)[N])
{
cout << sizeof(foo) << endl;
}
double bar[5];
char zot[3];
sub(bar); // ==> 40
sub(zot); // ==> 3
and you now have something that captures the abstract idea of "sub" regardless of the type or size of the array you pass it.
double foo()[5]. However, neither C nor C++ allow functions to return arrays.