Why is the implicit pointer pointer to pointer conversion finished?

I recently came across some code in stackoverflow, where pointers to pointers, where used to change allocated memory. When checking the code, I made a mistake to add an ampersand to the pointer, so make a pointer to a pointer that is still compiled by the compiler, and runtime errors have occurred. As an example

#include <stdio.h>

void func(int **p) {
  printf("Pointer is at %p\n", p);
}

int main(void) {
  int *p = 0;
  func(p);
  func(&p);
  int **pp = &p;
  func(&pp);
  return 0;
}

I understand that C has significantly lower restrictions for pointers than C ++, and allows something like char *buf = malloc(SIZE)that, although this is not allowed in C ++. I see this as a convenience because it happens in C.

, , , , , int int*. , , C.

.com, , , . clang, gcc, . , , .


PS, , SO - . , , .

+4
4

. , int* int**, int*** int**. int* int*** , int**, ; . ( , .)

gcc, ( gcc ), :

c.c: In function ‘func’:
c.c:4:3: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘int **’ [-Wformat=]
   printf("Pointer is at %x\n", p);
   ^
c.c: In function ‘main’:
c.c:9:3: warning: passing argument 1 of ‘func’ from incompatible pointer type [enabled by default]
   func(p);
   ^
c.c:3:6: note: expected ‘int **’ but argument is of type ‘int *’
 void func(int **p) {
      ^
c.c:12:3: warning: passing argument 1 of ‘func’ from incompatible pointer type [enabled by default]
   func(&pp);
   ^
c.c:3:6: note: expected ‘int **’ but argument is of type ‘int ***’
 void func(int **p) {
      ^

, (http://ideone.com/uzeXur).

+5

, -, :

int main()
{
    int *p = 0, **p2 = p;

...

$ gcc -std=c11 test.c -lncurses
test.c: In function ‘main’:
test.c:8:21: warning: initialization from incompatible pointer type [enabled by default]
  int *p = 0, **p2 = p;
                     ^

, gcc . . .

gcc -Werror : -Werror=<name of warning>. strict-aliasing.

, , . .

, , . 7. UB, ( ).

+2

, . -Wall - gcc

test_ptrs.c: In function ‘func’:
test_ptrs.c:4:3: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘int **’ [-Wformat=]
   printf("Pointer is at %x\n", p);
   ^
test_ptrs.c: In function ‘main’:
test_ptrs.c:9:3: warning: passing argument 1 of ‘func’ from incompatible pointer type [enabled by default]
   func(p);
   ^
test_ptrs.c:3:6: note: expected ‘int **’ but argument is of type ‘int *’
 void func(int **p) {
      ^
test_ptrs.c:12:3: warning: passing argument 1 of ‘func’ from incompatible pointer type [enabled by default]
   func(&pp);
   ^
test_ptrs.c:3:6: note: expected ‘int **’ but argument is of type ‘int ***’
 void func(int **p) {
+1

Using the wrong qualifier to print the data type causes undefined behavior. Change %xto %pand enter the argument printfin void *and you will get warnings.

Live Demo

+1
source

All Articles