As the code below, function pointer `y`, `z`, `b` behave the same. Even `*x` would be understand as data of pointer `x` and `&x` would understand as pointer to `x`.

```
typedef void (*func)(void);

void x(void){
    printf("asdsag\n");
    return;
}

int main(int argc, char const *argv[])
{
    func y = *x;
    func z = x;
    func b = &x;
    y();
    z();
    b();
    return 0;
}

```

Now look at this code.

```
void test(int **p){
    printf("%p\n",p);
    return;
}
int main(int argc, char const *argv[])
{
    int * p[5];
    test(p);
    test(&p);
    return 0;
}

```

This code print same pointer for all 3 case.
Here is asembly after compile above code

```
main:
    @ args = 0, pretend = 0, frame = 32
    @ frame_needed = 1, uses_anonymous_args = 0
    push    {r7, lr}
    sub sp, sp, #32
    add r7, sp, #0
    str r0, [r7, #4]
    str r1, [r7]
    ldr r3, [r7, #12]
    mov r0, r3
    bl  test
    add r3, r7, #12
    mov r0, r3
    bl  test
    add r3, r7, #12
    mov r0, r3
    bl  test
    movs    r3, #0
    mov r0, r3
    adds    r7, r7, #32
    mov sp, r7
    @ sp needed
    pop {r7, pc}
    .size   main, .-main

```

It is seem that they take same `r7+#12` for all three case.

**[Question]** For all given information above, what should I understand `p`,`*p`,`&p` in C99?

**[Info]** This is build with gcc-linaro-7.2.1-2017.11-x86\_64\_arm-linux-gnueabihf

**[Update]** Update for @tadman about imcompatible pointer

```
#include <stdio.h>

void test1(void **p){
    printf("%p\n",p);
    return;
}

void test2(void *p){
    printf("%p\n",p);
    return;
}

int main(int argc, char const *argv[])
{
    void * p[5] = {0};
    test1(p);
    test2(&p);
    return 0;
}

```

There is no warning even with `-Wall`
Here is the output:

```
0x7fff5615bb20
0x7fff5615bb20

```

P/S I was wrong in the first case, so I delete it.