Modern C++:Efficient and Scalable Application Development
上QQ阅读APP看书,第一时间看更新

Function parameters

As illustrated, there is an automatic conversion of an array to the appropriate pointer type and this occurs if you pass an array to a function, or return it from a function. This decay to a dumb pointer means that other code can make no assumption about an array size. A pointer could point to memory allocated on the stack where the memory lifetime is determined by the function, or a global variable where the memory lifetime is that of the program, or it could be to memory that is dynamically allocated and the memory is determined by the programmer. There is nothing in a pointer declaration that indicates the type of memory or who is responsible for the deallocation of the memory. Nor is there any information in a dumb pointer of how much memory the pointer points to. When you write code using pointers, you have to be disciplined about how you use them.

A function can have an array parameter, but this means a lot less than it appear to indicate:

    // there are four tires on each car 
bool safe_car(double tire_pressures[4]);

This function will check that each member of the array has a value between the minimum and maximum values allowed. There are four tires in use at any one time on a car, so the function should be called with an array of four values. The problem is that although it appears that the compiler should check that the array passed to the function is the appropriate size, it doesn't. You can call this function like this:

    double car[4] = get_car_tire_pressures(); 
if (!safe_car(car)) cout << "take off the road!" << endl;
double truck[8] = get_truck_tire_pressures();
if (!safe_car(truck)) cout << "take off the road!" << endl;

Of course, it should have been obvious to the developer that a truck is not a car, and so this developer should not have written this code, but the usual advantage of a compiled language is that the compiler will perform some sanity checks for you. In the case of array parameters, it won't.

The reason is that the array is passed as a pointer, so although the parameter appears to be a built-in array, you cannot use facilities you are used to using with arrays like ranged for. In fact, if the safe_car function calls sizeof(tire_pressures), it will get the size of a double pointer and not 16, the size in bytes of a four int array.

This decay to a pointer feature of array parameters means that functions will only ever know the size of an array parameter if you explicitly tell it the size. You can use an empty pair of square brackets to indicate that the item should be passed an array, but it really is just the same as a pointer:

    bool safe_car(double tire_pressures[], int size);

Here the function has a parameter that indicates the size of the array. The preceding function is exactly the same as declaring the first parameter to be a pointer. The following is not an overload of the function; it is the same function:

    bool safe_car(double *tire_pressures, int size);

The important point is that when you pass an array to a function, the first dimension of the array is treated as a pointer. So far arrays have been single dimensional, but they may have more than one dimension.