next up previous
Next: stream format Up: C++/C Previous: Declaring a global variable

Array Formal Argument

The name of array will automatically decay to the type of pointer to its first element; so for one dimension array
int ptr[10];
ptr just decays as the
int*

For the below code,see the comment;

void foo(double* buf) 
{}

// buf decays to double*
void bar(double buf[]) 
{}

// buf decays to double*, and 12 is ignored 
void goo(double buf[12])
{}

// no decay here, so 12 is kept by compiler
// and if we pass buf[3], compiler complains the mismatching of the size
void gar(double (&buf)[12])
{}

int main(int argc, char* argv[]) 
{
    double buf[3] = {1,2,3
    };

    foo(buf);
    bar(buf);
    goo(buf);

    // compilation error
    // can't conver the double (&)[3] to double (&)[12]
    gar(buf);
}

For multidimensional array, the formal argument is a pointer to an array; Note it is not a pointer to pointer (e.g., double **p), it a pointer to an array (e.g., double (*p)[3]); for example (see comment)

// this is formal argument type
// a multidimentional array decays to
// the pointer to an array
// but seoncd bounds are not decayed,
// because otherwise it would not be possible to
// performance pointer arithmetic with formal argument
void bar(double (*buf)[2]) 
{}

// Wrong!!
// since the multidimentional name decay to a pointer to array;
// not a pointer to pointer,
// complier will complian for it
void boo(double  **buf)
{}

// still wrong!
// since the formal argument decays to the pointer to the first element
// which is a pointer to dobule
// so actually buf = double**
void far(double* buf[2])
{}

// the first bounds is skiped
// so it can be whatever value;
void foo(double buf[3][2]) 
{}

// since first bound doesn't make sense
// just leave it empty
void goo(double buf[][2]) 
{}

// since the seoncd bounds doesn't decay
// the variable past to function
// it sencond bound has to be 3 
void gar(double buf[][3]) 
{}

int main(int argc, char* argv[]) 
{
    double buf[3][2] = {{1,1},{2,2},{3,3}};

    goo(buf);
    bar(buf);
    foo(buf);

    // cannot convert `double (*)[2]' to `double**'
    boo(buf);
    // cannot convert `double (*)[2]' to `double**'
    far(buf);
    // cannot convert `double (*)[2]' to `double (*)[3]'
    gar(buf);
}

For multidimentional array foo[i][j] is equal to *(*(foo+i) + j). Since int foo[i][j] is a contiguous memory chunk instead of an array of pointer to array, so (foo + i) has to move to the beginning of the ith row, that is why compiler has to know the bound of row. (i.e., int (*ptr)[][3]); for *(foo+i), since foo+i pointing to a row (an array), so *(foo+i) will automatically decayed to the pointer of first element in the row.



Wei Lu 2007-11-06