0

Suppose I have a function

void function(double p[2]) {
    cout << p[0] << " " << p[1] << endl;
}

If I try that following code

double a[1] = {1};
double b[2] = {2, 3};
double c[3] = {4, 5, 6};
function(a);
function(b);
function(c);

I get something like

1 2.0778e-317
2 3
4 5

In other words, the 2 seems to get completely ignored and all 3 arrays get passed to the function anyway.

Are the following exactly the same?

void function(double p[2])
void function(double p[])
void function(double *p)

If they are, is there any way to make a function that will only accept an array of a particular length or of at least a particular length? The reason I ask is that the types of a, b and c appear to be different. (You get different results for typeid(a).name() and typeid(b).name() for example).

Paul Boddington
  • 37,127
  • 10
  • 65
  • 116
  • To avoid decay you can get a reference to an array or a pointer to an array, but those are weird in C++: `void function(double (&p)[2])`, `void function(double (*p)[2])`. – rodrigo Oct 25 '15 at 17:26
  • @rodrigo How would I call those functions using `b`? – Paul Boddington Oct 25 '15 at 17:28
  • 1
    The reference one would be just `function(b)` and the pointer one `function(&b)`. But if you want to pass the 2 first values of `c` as argument (that a seasoned C++ developer will want to be able to do), you'll have to do some nasty casts. – rodrigo Oct 25 '15 at 17:31

1 Answers1

4

They are the same. An array function parameter gets adjusted to pointer. All information to do with array length is lost.

If you'd attempted to define these three functions, you would get multiple definition errors:

void function(double p[2]) {} // defines void function(double*)
void function(double p[]) {}  // ERROR
void function(double *p) {}   // ERROR

This confusing feature of the language is inherited from C.

To enforce that a function only accepts array arguments of a certain type, you can use a reference to array:

void function(const double(&p)[2]);

Note that parameter adjustment is not the same as array decay. Array decay is what happens when you call function with an array's name as argument, or when you simply assign an array to a pointer.

double a[42] = {};
function(a);    // a decays to double*
double * b = a; // a decays to double*
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • Thanks for the answer. So the fact that you get different results for `typeid(a).name()` etc does not mean that there is any way to declare a variable or parameter to be of type `A2_d` for example? – Paul Boddington Oct 25 '15 at 17:24
  • @PaulBoddington That's right. In fact, I admit to being surprised that this produces different type IDs. – juanchopanza Oct 25 '15 at 17:26
  • You can declare a reference to an array, which does preserve the size information. – n. m. could be an AI Oct 25 '15 at 17:29
  • @n.m. Right. Or I would say it *enforces* that the argument be an array of a particular type (which can be of course by deduced in a function template.) – juanchopanza Oct 25 '15 at 17:31