Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why does the array decay to a pointer in a template function

I don't understand why the array decays to a pointer in a template function.

If you look at the following code: When the parameter is forced to be a reference (function f1) it does not decay. In the other function f it decays. Why is the type of T in function f not const char (buff&)[3] but rather const char* (if I understand it correctly)?

#include <iostream>

template <class T>
void f(T buff) {
    std::cout << "f:buff size:" << sizeof(buff) << std::endl;       //prints 4
}

template <class T>
void f1(T& buff) {
    std::cout << "f:buff size:" << sizeof(buff) << std::endl;       //prints 3
}

int main(int argc, char *argv[]) {
    const char buff[3] = {0,0,0};
    std::cout << "buff size:" << sizeof(buff) << std::endl;         //prints 3
    f(buff);
    f1(buff);
    return 0;
}
like image 997
David Feurle Avatar asked Oct 17 '11 18:10

David Feurle


People also ask

Why do array decay into pointers?

From Code 1, whenever arrays are passed as the arguments to functions, they are always passed by using the 'Pass by reference' mechanism. Because of this, they will decay into pointers in the function parameters.

Does STD array decay to pointer?

You probably heard that "arrays are pointers", but, this is not exactly true (the sizeof inside main prints the correct size). However, when passed, the array decays to pointer. That is, regardless of what the syntax shows, you actually pass a pointer, and the function actually receives a pointer.

Why are arrays treated as pointers in C?

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.


1 Answers

It is because arrays cannot be passed by value to a function. So in order to make it work, the array decays into a pointer which then gets passed to the function by value.

In other words, passing an array by value is akin to initializing an array with another array, but in C++ an array cannot be initialized with another array:

char buff[3] = {0,0,0};
char x[3] = buff; //error 

So if an array appears on the right hand side of =, the left hand side has to be either pointer or reference type:

char *y = buff; //ok - pointer
char (&z)[3] = buff; //ok - reference

Demo : http://www.ideone.com/BlfSv

It is exactly for the same reason auto is inferred differently in each case below (note that auto comes with C++11):

auto a = buff; //a is a pointer - a is same as y (above)
std::cout << sizeof(a) << std::endl; //sizeof(a) == sizeof(char*)

auto & b = buff; //b is a reference to the array - b is same as z (above)
std::cout << sizeof(b) << std::endl; //sizeof(b) == sizeof(char[3])

Output:

4 //size of the pointer
3 //size of the array of 3 chars

Demo : http://www.ideone.com/aXcF5

like image 150
Nawaz Avatar answered Sep 23 '22 19:09

Nawaz