Home > Guides > Programming > C/C++

Toggle Open Guide Table of ContentsGuide Contents

Close Table of ContentsGuide Contents

Close Table of Contents

Passing an Array to a Function

Last updated Jun 17, 2005.

In a previous column, I claimed that passing an array as a function argument was impossible. The problem is that the array is implicitly converted, or decays, into a pointer. The pointer, alas, doesn't store the array's dimension; it doesn't even tell you that the variable in question is an array. I recently received an e-mail message from a reader who proposed a technique for passing arrays as arguments without the implicit conversion to pointers. Here it is:

"I'm not sure you are correct when you say in your article that functions in C++ can't receive array arguments. I have written functions that take array arguments before. It only works for statically sized arrays, and the parameter has to specify the size of the array, but it is possible. The syntax is something like:

void foo(int (&array)[10]);

which declares a function that takes an array of 10 integers. This does not seem useful at first, but by using template parameter deduction you can write generic functions that operate on statically sized arrays in this way:

template <typename T, size_t size>

void foo(T (&array)[size])
{
 //sort array, find the sum, min, max, etc
}

Of course as you say in your article, you have to be careful that the array does not decay to a pointer as you are passing it around. In this case though, the code should simply not compile since the template will not match."

Before I go on, let's parse the following function declaration, which might look a bit cryptic:

void foo(int (&array)[10]);

What's interesting here is how the parameter is declared: int (&array)[10] is a reference to an array of 10 ints. So, what gets passed on the callee's stack is actually a reference, not a real array; though, for most practical purposes, there is no difference between the two. (For a review of the three argument passing mechanisms of C++, see this section.)

Unlike passing an array by value, which causes the array to decay into a bare pointer, the use of a reference to a statically-allocated array is seemingly safer, because the callee has access to the type information associated with the array. Particularly, a sizeof() expression returns the correct array size even when used inside the callee:

void foo(int (&arr)[10])
{
 cout<<sizeof(arr)<<endl; //output: 40
}
int main()
{
 int arr[10];
 foo(arr);
}

When you use a reference to a statically sized array, the compiler is also capable of detecting type mismatches at the place of all:

int arr[5]; //wrong dimension
foo(arr); //compiler diagnostic

There are a few caveats here, though. The main problem is that a reference to an array is a slippery type -- you can inadvertently convert it to a bare pointer, thus losing important type information. Consider the following example:

void func(int* p) {}
void foo(int (&arr)[10])
{
 func(arr);
}

When func() is called, the argument arr decays into a pointer. Remember: once an array has decayed into a pointer, the array's type information is lost. This isn't the only problem that might arise, though. Consider the following typeid() expression. I expected it to produce a complete description of the array's type, including its dimension:

void foo(int (&arry)[10])
{
 cout<<typeid(arry).name()<<endl;
}

However, the cout expression reports "int *". We can conclude that there are limits as to how far you can push this technique. If it isn't used in generic functions that operate on statically sized arrays, I still recommend the array_wrapper class template presented in the original column as it offers a safer and efficient alternative.

Discussions

Bugzilla
Posted Nov 18, 2008 01:53 AM by cupu
2 Replies
auto_ptr issues
Posted Sep 14, 2007 07:43 AM by singh_siddhu
1 Replies
i want c++ book through net
Posted Aug 23, 2007 11:13 PM by harivilu
3 Replies

Make a New Comment

You must log in in order to post a comment.

Related Resources

Danny KalevMinutes from the October 2009 Meeting
By Danny KalevNovember 19, 2009 No Comments

The minutes from the Santa Cruz (October 2009) meeting are available here. Even if you're not a language layer at heart, I encourage you to read them.

Danny KalevA Reader's Opinion on Attributes
By Danny KalevOctober 20, 2009 No Comments

In August I dedicated a series to the debate about C++0x attributes. I believe that it covered the subject in a balanced and detailed way, but I keep getting complaints from C++ users who don't like attributes for various reasons. Here's a recent email I received from a Polish C++ programmer. While it  doesn't represent my opinion about attributes -- I'm rather neutral about this feature and consider it a "solution waiting for a problem" -- but it suggests that attributes are still a highly controversial issue that will haunt C++ for a long time. The email is quoted here with minor edits that and as usual, with all private details removed.

Danny KalevFollowup: The Web 2.0 Guy I Ain't
By Danny KalevOctober 16, 2009 1 Comment

Almost a year ago, I posted here The Web 2.0 Guy I Ain't. People wonder whether I still resist all those Web 2.0 features and technologies at the end of 2009.

See More Blogs

Informit Network