Why am I getting an error converting a ‘float**’ to ‘const float**’?
I have a function that receives float**
as an argument, and I开发者_开发技巧 tried to change it to take const float**
.
The compiler (g++
) didn't like it and issued :
invalid conversion from ‘float**’ to ‘const float**’
this makes no sense to me, I know (and verified) that I can pass char*
to a function that takes const char*
, so why not with const float**
?
See Why am I getting an error converting a Foo** → const Foo**?
Because converting
Foo**
→const Foo**
would be invalid and dangerous ... The reason the conversion fromFoo**
→const Foo**
is dangerous is that it would let you silently and accidentally modify a const Foo object without a cast
The reference goes on to give an example of how such an implicit conversion could allow me one to modify a const
object without a cast.
This is a very tricky restriction. It is related to the aliasing rules of the language. Take a look at what the standards say, because I have faced this once before:
(Page 61)
[Note: if a program could assign a pointer of type T** to a pointer of type const T** (that is, if line //1 below was allowed), a program could inadvertently modify a const object (as it is done on line //2). For example,
int main() { const char c = 'c'; char* pc; const char** pcc = &pc; //1: not allowed *pcc = &c; *pc = 'C'; //2: modifies a const object }
—end note]
Other anwers have detailled why this is an error in C++.
Let me address the question behind your question. You wanted to state, in the interface of your function, that your function will not modify float values contained in the array. Nice intention, and enables that your function is called with const float **
arrays. The question behind your question would be, how to achieve this without resolving to ugly casts.
The correct way to achieve what you wanted is to change the type of your function parameter to const float * const *
.
The additional const
between the stars assures the compiler that your method will not try to store pointers to const float in the array, since this type declares that the pointer values are also const.
You can now call this function with float **
(which was the example in your question), const float **
, and const float * const *
arguments.
If you converted the parameter to const float**
you could then store a const float*
at the memory location where the parameter points to. But the calling function thinks that this memory location is supposed to contain a non-const float*
and might later try to change this pointed-to float
.
Therefore you cannot cast a float**
to a const float**
, it would allow you to store pointers to constants in locations where pointers to mutable values are expected.
For more details see the C++ FAQ Lite.
精彩评论