const导致指针类型不兼容.为什么只为双指针? [英] const causing incompatible pointer type. Why only for double pointers?

查看:112
本文介绍了const导致指针类型不兼容.为什么只为双指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此处.

建议的重复并且当前给出的答案没有解决为什么前面给出的示例没有问题.主要是为什么不这样做:

The suggested duplicate and the currently given answers don't address why there aren't issues with the examples given first. Mainly why doesn't the reasoning:

"const int ** is a pointer to const int *int*"

也申请:

"const int * is a pointer to const intint"不同

我正从不同的角度来研究它,希望能得到另外的解释.

I am approaching it from a different angle to hopefully get another explanation.

带有示例的代码.

#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]
}

被广泛接受的答案是这样的:

The accepted widely accepted answer goes something like this:

int **与const int **不同,您无法安全地强制转换

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:

It didn't complain here because int * isn't neither int const * nor int * const:

int * ptr_a = &a;
f_ptr_a_type1(&a);
f_ptr_a_type2(&a);

但是突然之间,它在双指针情况下开始抱怨.

But suddenly it starts complaining in the double pointer case.

  • 是否正在寻找使用此术语和示例的解释?

  • Looking for explanations using this terminology and example?

为什么函数突然开始担心写入 权限超出了她的权限范围?

Why does the function suddenly starts worrying about write permissions of something that is outside of her scope?

推荐答案

为什么函数突然开始担心写权限 超出她的能力范围?

Why does the function suddenly starts worrying about write permissions of something that is outside of her scope?

这不是从功能参数的角度来看投诉.该参数的行为将与预期的一样 函数作用域,并且不受变量在进入函数作用域之前发生的情况的影响.

It's not that the complaint comes from the point of view of the function parameter. The parameter will behave just as expected inside the function scope and isn't affected by what happens with the variable before it enters the scope of the function.

void f_ptr_ptr_a (int const ** ptr_ptr_a){
    /*
     *  Can't do:
     *      ** ptr_ptr_a = 3;  //error: assignment of read-only parameter ‘**ptr_a’
    */
}

int const ** ptr_ptr_a进入要通过复制值复制的功能范围,不允许更改** ptr_ptr_a.该错误与无关 变量按值复制后的样子.

int const ** ptr_ptr_a enters the function scope being copied by value disallowing a change of ** ptr_ptr_a. The error has nothing to do with what the variables were like once they have been copied by value.

由于函数调用期间发生隐式强制转换而产生错误.剖析呼叫f_ptr_ptr_a(ptr_ptr_a);我们得到:

The error arises due to an implicit cast happening during the function call. Dissecting the call f_ptr_ptr_a(ptr_ptr_a); we get:

int const ** ptr_ptr_x = ptr_ptr_a;     //This line causes the warning
f_ptr_ptr_a(ptr_ptr_x);


是否正在寻找使用此术语和示例的解释?

Looking for explanations using this terminology and example?

现在让我们将示例剥离为基本内容.

Let's now strip the example to the bare basics.

int main()
{
int a = 3;
int * ptr_a = &a;
int ** ptr_ptr_a = &ptr_a;        // I promise here **ptr_ptr_a will always be the same


int const b = 5;
int const * ptr_b = &b;
int const ** ptr_ptr_b = &ptr_b;

ptr_ptr_b = ptr_ptr_a;                  // Warning here: -Wincompatible-pointer-types-discards-qualifiers
printf("%d\n", ** ptr_ptr_b);           // Look at me, I've just changed the value of const ** int.

** ptr_ptr_a = 15;
printf("%d\n", ** ptr_ptr_b);            // I did it again.

}

由于隐式强制转换,编译器正在警告我们.

The compiler is warning us because of the implicit casting.

int main()
{
    int const a = 3;
    int const * ptr_a = &a;
    int const ** ptr_ptr_a = &ptr_a;        // I promise here **ptr_ptr_a will always be the same

    int const b = 5;
    int const * ptr_b = &b;
    int const ** ptr_ptr_b = &ptr_b;

    ptr_ptr_b = ptr_ptr_a;
    printf("%d\n", ** ptr_ptr_b);           // Look at me, I've just changed the value of const ** int.
                                            // And there were no warnings at all. Har har har har!
}

我可以从这个问题中得出一个结论,从当前的角度来看,它可以带来不必要的复杂性.

There is one conclusion I can take out from this question and the, from the current perspective, unnecessary complexities it introduces.

请始终记住,通过解引用访问与直接访问不同.

我们在这里看到了. const限定符实际上正在执行应做的事情,从而阻止我们通过取消引用机制更改** ptr_ptr_b. 当然,我们已经设法改变了只读值,但这仅仅是因为我们要向穷人const提出很多要求.

We saw it here. The const qualifier is actually doing what it should, preventing us from changing ** ptr_ptr_b through the mechanism of dereferencing. Sure, we have managed to apparently change the read only value, but that is just because we're asking to much from the poor const.

sheu在此处

const char c = 'A';
char* ptr;
const char** const_ptr = &ptr;  // <-- ILLEGAL, but what if this were legal?
*const_ptr = &c;
*ptr = 'B';  // <- you just assigned to "const char c" above.

printf("%c \n", c);
printf("%c \n", *ptr);

当您说you just assigned to "const char c" above时,这是不正确的,只是引用抽象失控了.

When you say you just assigned to "const char c" above, that isn't true, it's just the reference abstraction getting out of hand.

这篇关于const导致指针类型不兼容.为什么只为双指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆