Click here to Skip to main content
15,891,423 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello.

When I write these functions:

C++
void f(float* p[3])
{
	cout << "ARRAY OF [3] POINTER TO FLOAT" << endl;
}

void f(float** p)
{
	cout << "POINTER TO POINTER" << endl;
}


The compiler complains: void f(float*[]) already has a body

What's going on?

What I have tried:

C++
void f(float* p[3])
{
	cout << "ARRAY OF [3] POINTER TO FLOAT" << endl;
}

void f(float** p)
{
	cout << "POINTER TO POINTER" << endl;
}

int main()
{
   float pos[3] {1.3f, 4.3f, 5.3f};

   f(&pos);  // error: can't convert float(*)[3] to float**
}
Posted
Updated 1-Jul-16 14:40pm
v2
Comments
Philippe Mori 2-Jul-16 9:35am    
Although it is useful to know that stuff, one should prefer to use STL containers (std::vector...) and avoid low level C stuff to make the code more robust.

As you can see, your first 2 functions declare the same function. This would be similar to:
C++
void g(float p[3]) { /* ... */ }

vs
C++
void g(float *p) { /* ... */ }

You can call either of these function (assuming only one is declared and defined) like this:
C++
float pos[3] {1.3f, 4.3f, 5.3f};
g(pos);


Thus if you want to call your functions as declared, you would have to do it like this:
C++
float *arrayOfPointers[3] = { &pos[0], &pos[1], &pos[2] };
f(arrayOfPointers);


On the other hand, if you want to call the function as in your code, then you need to modify the declaration like this:
C++
void f(float (*p)[3]) { /* ... */ }

That way, you declare a pointer to an array. You might want to use a typedef instead.
By the way, if you use that declaration, the array size must match as it will be part of the declaration.

At that point,you can also remarks that your original error message show you the syntax of a pointer to an array of 3 floats...

Bonus
In C++, you can also use references. I prefer that as we don't need to take the address of the array at the calling site and it will also allows you to ensure that only array of 3 items can be passed to the function.
C++
void h(float (&p)[3]) { /* ... */ }
h(pos);


Update
An array of pointer would be:
C++
float f1 = 1.1f, f2 = 2.2f, f3 = 3.3f;
float *arrayOfPointers[] = { &f1, &f2, &f3 };

The memory representation would look like:
[ &f1 | &f2 | &f3 ]

Since an array is equivalent to a pointer, then float ** would declare a pointer to the first item which is a pointer to a float.

A pointer to an array of float would be:
C++
float arrayOfFloats[] = { 1.11f, 2.22f, 3.33f };
float (*pointerToAnArrayOfFloats)[] = &arrayOfFloats;

The memory representation would look like:
& [ f1 | f2 | f3 ]


Extra links
Are pointers and arrays equivalent in C? - Eli Bendersky's website[^]
There is a nice graphical representation that would help you understand the difference.

C Pointer to Pointer, Pointer to Functions, Array of Pointers Explained with Examples[^]
 
Share this answer
 
v3
Comments
[no name] 1-Jul-16 20:53pm    
Very precise.
Philippe Mori 2-Jul-16 9:23am    
Yes original information should have been enough...
gedamial 2-Jul-16 4:17am    
We know that void f(float p[3]) the compiler evaluates this to void f(float* p)

Why doesn't the compiler evaluate void f(float (*p)[3]) to void f(float** p) ?
Philippe Mori 2-Jul-16 6:40am    
You are better to read documentation on C++ syntax. Essentially, you have to read declaration backward and the () make the pointer apply to the whole declaration (variable p) instead of float *.
gedamial 2-Jul-16 8:34am    
I know that.

I mean, if float(*p)[3] is a pointer-to-array, and an array decays into a pointer, then float** should be the same thing!
Pointers - C++ Tutorials[^]

This declares an array of floats.
float pos[3] {1.3f, 4.3f, 5.3f};


Nowhere do you have an array of pointers to floats which would be declared thus:
C++
float *pos[3];


So with what you declared you you can have:
void f(float p[3])

OR
void f(float* p)

NOT both.
 
Share this answer
 
v2
Comments
gedamial 2-Jul-16 4:09am    
So, in short, array-of-pointers and pointer-to-pointer are the same thing?
Philippe Mori 2-Jul-16 9:33am    
Yes from the point of view of the compiler... but for code maintainability, you should use the appropriate syntax to make your intent clear.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900