这个问题已经解决了
here.
建议的duplicate和当前给出的答案没有解决为什么首先给出的例子没有问题.主要是为什么没有推理:
“const int **是指向const int *的指针,它与int *不同”
也适用于:
“const int *是一个指向const int的指针,它与int只是一个不同的东西”
我从不同的角度接近它,希望得到另一种解释.
带有示例的代码.
#include <stdio.h> void f_a (int const a){ /* * Can't do: * a = 3; //error: assignment of read-only parameter ‘a’ * * Explanation: I can't change the value of a in the scope of the function due to the const */ printf("%d\n",a); } void f_ptr_a_type1 (int const * ptr_a){ /* * Can do this: * ptr_a’ = 0x3; * which make dereferencig to a impossible. * printf("%d\n",* ptr_a’); -> segfault * But const won't forbid it. * * Can't do: * *ptr_a’ = 3; //error: assignment of read-only parameter ‘* ptr_a’ * * Explanation: I can't change the value of a by pointer dereferencing and addignment due to the int const */ } void f_ptr_a_type2 (int * const ptr_a){ /* * Can do this: * *a = 3; * * Can't do: * ptr_a = 3; //error: assignment of read-only parameter ‘ptr_a’ * * Explanation: I can't change the value because the const is protecting the value of the pointer in the funcion scope */ } void f_ptr_ptr_a (int const ** ptr_ptr_a){ /* * Can do this: * ptr_ptr_a = 3; * * ptr_ptr_a = 0x3; * * Can't do: * ** ptr_ptr_a = 0x3; //error: assignment of read-only parameter ‘**ptr_a’ * * Explanation: Makes sense. Just follows the pattern from prevIoUs functions. */ } int main() { int a = 7; f_a(a); int * ptr_a = &a; f_ptr_a_type1(&a); f_ptr_a_type2(&a); int ** ptr_ptr_a = &ptr_a; f_ptr_ptr_a(ptr_ptr_a); //warning: passing argument 1 of ‘f_ptr_ptr_a’ from incompatible pointer type [-Wincompatible-pointer-types] }
接受的广泛接受的答案是这样的:
int ** isn’t the same as const int** and you can’t safely cast it
我的问题是为什么功能突然关注?
这里没有抱怨int不是int const:
int a = 7; f_a(a);
它没有在这里抱怨因为int *既不是int const *也不是int * const:
int * ptr_a = &a; f_ptr_a_type1(&a); f_ptr_a_type2(&a);
但突然间,它开始在双指针案件中抱怨.
>使用这个术语和示例寻找解释?
>为什么函数突然开始担心写入
超出范围的东西的权限?
解决方法
从例如转换char *到const char *总是安全的.通过const char *,指向的数据无法修改,就是这样.
另一方面,从char **到const char **的转换可能是不安全的,因此不允许隐式.请考虑以下代码,而不是解释它:
void foo(const char **bar) { const char *str = "test string"; *bar = str; // perfectly legal } int main(void) { char *teststr[] = {0}; foo((const char **)teststr); // now teststr points to a `const char *`! *teststr[0] = 'x'; // <- attempt to modify read-only memory // ok in this line,there's no const qualifier on teststr! }
如果在调用foo()时从char **到const char **的转换是隐式的,那么你将有一种隐式转换const的方法.