I'm very confused. I saw that when the code be like
void fun(const char **p) { }
int main(int argc, char **argv)
{
fun(argv);
getchar();
return 0;
}
And it shows error: invalid conversion from 'char**' to 'const char**'
But when the code be like
void test(const char *p) { }
int main()
{
char *c = new char('a');
test(c);
}
Then there is no compile error. What is the difference between two codes?
Why can the second code pass a variable to the function with constant parameter?
Pointers to pointers are weird. Take this example
Clearly you should not be able to defeat
constjust by assigning pointers around, so the conversion fromT**toconst T**is illegal.But wait a minute, why is converting
T*toconst T*legal in the first place?Right, it's because each
Tcan be treated as aconst T. Aconst Tis only a restriction ofT. No operation onconst Twill be illegal onT. If you view types as representing a set of legal operations on objects, thenconst Trepresents a subset ofT.However, restricting the pointee has the opposite effect on the pointer. A
const T*is not a subset ofT*. AT*can only point to non-constTwhileconst T*can point to anyT. In terms of just assignment on the pointer itself,const T*is a superset ofT*†, not the other way around.So why isn't a conversion from
T**toconst T**legal? BecauseT*is not a superset ofconst T*: not allT*can be treated as aconst T*, as demonstrated by the opening snippet.†But if you dereference the pointer,
const Tis a subset ofTagain, soconst T*andT*aren't subsets of each other.