code 1:

void fun(const int **);

    int main()
    {
          int **p;

          fun(p);
    }

code 2:

void fun(const int **);

    int main()
    {
          const int **p;

          fun(p);
    }

code 1 is compile error and 2 is not. can you explain why ? as per my knowledge, we can convert a non-const to const but we cant change const to non-const. and even to prove this, when i repace the above with "pointer to int" and everything remain same, then it works. then what is hidden in double pointer conversion fron int ** to const int **. thanks in advance.

yeah, firstly. but after asked by you , i compiled as .c and it is giving me warning now. not error. can you explain these things sir ?

I'll explain by giving you some homework. The answer to the following question will also give you a hint on your current question.

Q: What's the difference between void* and void**?

void *

is a pointer to nothing , and void ** is a pointer which is pointer to pointer which points to nothing. I wish i am correct.

like when i have int p , nothing is int and when i have char *p, nothing is char and when i have void means it is a pointer which is not pointing to any specific data type. and it is used just for using for functions like malloc which need to allocate memory for any type of data type pointers. for ex: void * g; it mean g is pointer to some unknown data type.

P.S (don't know why * are not there even if i am writing them !)

Edited 3 Years Ago by nitin1

Yeah...no.

A pointer to void is a generic object pointer, it can point to any object type (but not a function pointer type). For example, the following code has no errors:

void foo(void *p) { }

int main(void)
{
    int *a;
    char *b;
    double *c;

    foo(a);
    foo(b);
    foo(c);

    return 0;
}

int*, char*, and double* are all compatible with void* and can be safely converted to void*. Likewise, in C a void* can be implicitly converted back without a cast. That's why you don't need to cast malloc() even though it returns a pointer to void:

char *p = malloc(10); /* No cast needed! */

The reason I asked about void* and void** is to introduce you to this subtle little error:

void foo(void **p) { }

int main(void)
{
    int **a;

    foo(a);

    return 0;
}

The "genericalness" no longer applies. p is a pointer to a pointer to void, not a pointer to a pointer to some undisclosed object type. Therefore int** is not compatible, and the only type you can pass into foo() is a void**.

The reason I gave you this question is because const has somewhat similar behavior. You can convert int* to const int*, but int** and const int** are incompatible for the same reason as with void* and void**. The added level of indirection is the culprit.

Edited 3 Years Ago by deceptikon

Comments
Excellent explanation.

firstly what was "yeah...no", means partial right , partial wrong ?

secodnly, i got it what u told me. but why generality doesn't work at that level ? i mean in case int**p , but not in case of int* ? i didn't get this point only. thanks.

P.S awesome example, i have noted it down.

firstly what was "yeah...no", means partial right , partial wrong ?

Completely wrong. Not even close. ;) Sadly, the "yeah...no" thing doesn't translate to a strictly text medium very well.

but why generality doesn't work at that level ?

Perhaps this tutorial will help.

sir, it is teaching me pointers to pointers which i am well aware of. i got the point that void * is undisclosed data type pointer , that's why it is okay to do, but void ** is disclosed data type pointer as it is pointing to a pointer (which is specified). it is okay! i got it. can i related this thing to const thing also ?

Edited 3 Years Ago by nitin1

This article has been dead for over six months. Start a new discussion instead.