这个问题已经解决了
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的方法.