When compiling the following code:
void DoSomething(int Numbers[]) { int SomeArray[] = Numbers; }
the VS2005 compiler complains with the error C2440: ‘initializing’ : cannot convert from ‘int []’ to ‘int []’
I understand that really it’s trying to cast a pointer to an array which is not going to work. But how do you explain the error to someone learning C++?
There are three things you need to explain to the person you’re trying to help:
Arrays can’t be passed by value to a function in C++. To do what you are trying to do, you need to pass the address of the start of the array to
DoSomething(), as well as the size of the array in a separateint(well,size_t, but I wouldn’t bother saying that) argument. You can get the address of the start of some arraymyArraywith the expression&(myArray[0]). Since this is such a common thing to want to do, C++ lets you use just the name of the array — e.g.myArray— to get the address of its first element. (Which can be helpful or confusing, depending on which way you look at it.) To make things even more confusing, C++ allows you to specify an array type (e.g.int Numbers[]) as a parameter to a function, but secretly it treats that parameter as though it was a declared as a pointer (int *Numbersin this case) — you can even doNumbers += 5insideDoSomething()to make it point to an array starting at the sixth position!When you declare an array variable such as
SomeArrayin C++, you must either provide an explicit size or an ‘initialiser list’, which is a comma-separated list of values between braces. It’s not possible for the compiler to infer the size of the array based on another array that you are trying to initialise it with, because…You can’t copy one array into another, or initialise one array from another in C++. So even if the parameter
Numberswas really an array (say of size 1000) and not a pointer, and you specified the size ofSomeArray(again as say 1000), the lineint SomeArray[1000] = Numbers;would be illegal.To do what you want to do in
DoSomething(), first ask yourself:Numbers?If the answer to either question is ‘No’, you don’t in fact need to make a copy of
Numbersin the first place — just use it as is, and forget about making a separateSomeArrayarray.If the answer to both questions is ‘Yes’, you will need to make a copy of
NumbersinSomeArrayand work on that instead. In this case, you should really makeSomeArraya C++vector<int>instead of another array, as this really simplifies things. (Explain the benefits of vectors over manual dynamic memory allocation, including the facts that they can be initialised from other arrays or vectors, and they will call element constructors when necessary, unlike a C-stylememcpy().)