Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When a function has a specific-size array parameter, why is it replaced with a pointer?

Given the following program,

#include <iostream>  using namespace std;  void foo( char a[100] ) {     cout << "foo() " << sizeof( a ) << endl; }  int main() {     char bar[100] = { 0 };     cout << "main() " << sizeof( bar ) << endl;     foo( bar );     return 0; } 

outputs

main() 100 foo() 4 
  1. Why is the array passed as a pointer to the first element?
  2. Is it a heritage from C?
  3. What does the standard say?
  4. Why is the strict type-safety of C++ dropped?
like image 234
CsTamas Avatar asked Aug 25 '09 13:08

CsTamas


People also ask

Why are arrays treated as pointers?

C treats array parameter as pointers because it is less time consuming and more efficient. Though if we can pass the address of each element of the array to a function as argument but it will be more time consuming.

Why is an array not a pointer?

sizeof(pointer) is always the same, regardless of the number of elements the pointer addresses, or the type of those elements. sizeof(array depends on both the size of the array, and the element type. Arrays cannot have zero length.

How do you pass an array to a function with pointer?

A whole array cannot be passed as an argument to a function in C++. You can, however, pass a pointer to an array without an index by specifying the array's name. In C, when we pass an array to a function say fun(), it is always treated as a pointer by fun().


2 Answers

Yes it's inherited from C. The function:

void foo ( char a[100] ); 

Will have the parameter adjusted to be a pointer, and so becomes:

void foo ( char * a ); 

If you want that the array type is preserved, you should pass in a reference to the array:

void foo ( char (&a)[100] ); 

C++ '03 8.3.5/3:

...The type of a function is determined using the following rules. The type of each parameter is determined from its own decl-specifier-seq and declarator. After determining the type of each parameter, any parameter of type "array of T" or "function returning T" is adjusted to be "pointer to T" or "pointer to function returning T," respectively....

To explain the syntax:

Check for "right-left" rule in google; I found one description of it here.

It would be applied to this example approximately as follows:

void foo (char (&a)[100]); 

Start at identifier 'a'

'a' is a

Move right - we find a ) so we reverse direction looking for the (. As we move left we pass &

'a' is a reference

After the & we reach the opening ( so we reverse again and look right. We now see [100]

'a' is a reference to an array of 100

And we reverse direction again until we reach char:

'a' is a reference to an array of 100 chars

like image 66
Richard Corden Avatar answered Oct 02 '22 14:10

Richard Corden


Yes. In C and C++ you cannot pass arrays to functions. That's just the way it is.

Why are you doing plain arrays anyway? Have you looked at boost/std::tr1::array/std::array or std::vector?

Note that you can, however, pass a reference to an array of arbitrary length to a function template. Off the top of my head:

template< std::size_t N > void f(char (&arr)[N]) {   std::cout << sizeof(arr) << '\n'; } 
like image 23
sbi Avatar answered Oct 02 '22 16:10

sbi