Thread: warning: passing argument 1 of 'foo' from incompatible pointer type

  1. #1
    Registered User
    Join Date
    Feb 2022
    Posts
    73

    warning: passing argument 1 of 'foo' from incompatible pointer type

    I am doing experiements with code to understand pointer

    Code:
     #include <stdio.h>#include <stdlib.h>
    
    
    void foo ( int *p)
    {
    	int *q = malloc(sizeof(*q));
    	if ( q != NULL )
    	{
    
    
    	}	  
     }
    int main ()
    {
    
    
      int *p = NULL;
      
      foo (p);
      
      return 0;
    }
    This code compile without warning. Program pass the content of pointer p

    When I change line to pass location of pointer variable P I get warnings

    Code:
      foo (&p);
    warnings
    Code:
     hello.c:17:8: warning: passing argument 1 of 'foo' from incompatible pointer type [-Wincompatible-pointer-types]   foo (&p);
            ^
    hello.c:4:6: note: expected 'int *' but argument is of type 'int **'
     void foo ( int *p)
    I want to understand why this warning generates and why it resolve by declearing double pointer

  2. #2
    Registered User
    Join Date
    Feb 2022
    Location
    Canada, PEI
    Posts
    64
    Did you read the warning message?

    expected 'int *' but argument is of type 'int **'

  3. #3
    Registered User
    Join Date
    Feb 2022
    Posts
    73
    Quote Originally Posted by G4143 View Post
    Did you read the warning message?
    I want to understand why this warning resolve by declearing double pointer

  4. #4
    Registered User
    Join Date
    Feb 2019
    Posts
    985
    Think of a pointer as a normal integer variable... If you do:
    Code:
    void f(int x) { x = 1; }
    ...
    int a = 3;
    f(a);
    a isn't modified, isn't it?

    If you do:
    Code:
    void f(int *p) { p = malloc(4*sizeof(int)); }
    And you do:
    Code:
    int *q;
    
    f(q);
    q won't be modified either...
    But if you do:
    Code:
    void f( int **p )
    { *p = malloc( 4 * sizeof(int) ); }
    ...
    int *q;
    
    f(&q);
    q is an object which holds the address of another... &q is the address of an object which holds the address of another. You are changing the address which q holds, not q it self.

  5. #5
    Registered User
    Join Date
    Apr 2021
    Posts
    92
    In C, the address-of operator creates a pointer. That is, if you declare
    Code:
        typedef ... Foo;
    
        Foo   foo_var;
    
        Foo * foo_ptr = &foo;
    The last line will compile perfectly well because they type of foo_ptr is Foo *, and the combination of foo_var being type Foo and the & operator taking the address yields a Foo *.

    If you tell the compiler that a function takes a pointer to some type, it doesn't care how you generate the pointer. But it does verify that what you are passing is the correct type.

    You can declare a variable that holds pointers (Foo * foo_ptr) and pass the value of that variable. Or you can declare a variable that does not hold a pointer, and take the address of it (Foo foo_var; ... &foo_var ...). Or, you could declare a double-pointer and dereference it (Foo ** foo_2ptr; ... *foo_2ptr ...). You could even take something completely wrong, and (cast) it to the right type. All of those expressions produce a value that has type Foo *, which is what the compiler cares about.

    Now in your example, you declared a function foo that takes an int * parameter. So you are obligated to pass in values that have type int *. You can produce the int * by any means you like. The compiler is just going to check that what you produce has the correct type.

    Code:
        extern void foo(int *);
    
        int
        main(void)
        {
            int ival = 0;
    
            foo(&ival);      // take the address of an int
    
            int * iptr;
    
            foo(iptr);       // Pass an int* directly
    
    
            int **idp;
    
            foo(*idp);      // Dereference a double-pointer to yield a single-pointer
            foo(idp[3]);
    
     
            char name[] = "George";
    
            foo((int*)name);    // Use an explicit cast. This works, but you had better know EXACTLY what you're doing.
        }

  6. #6
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    969
    Quote Originally Posted by Dadu@ View Post
    I am doing experiements with code to understand pointer

    Code:
     #include <stdio.h>#include <stdlib.h>
    
    
    void foo ( int *p)
    {
    	int *q = malloc(sizeof(*q));
    	if ( q != NULL )
    	{
    
    
    	}	  
     }
    int main ()
    {
    
    
      int *p = NULL;
      
      foo (p);
      
      return 0;
    }
    This code compile without warning. Program pass the content of pointer p

    When I change line to pass location of pointer variable P I get warnings

    Code:
      foo (&p);
    warnings
    Code:
     hello.c:17:8: warning: passing argument 1 of 'foo' from incompatible pointer type [-Wincompatible-pointer-types]   foo (&p);
            ^
    hello.c:4:6: note: expected 'int *' but argument is of type 'int **'
     void foo ( int *p)
    I want to understand why this warning generates and why it resolve by declearing double pointer
    Please study the code below, that hopefullly will explain the error message you received:
    Code:
    #include <stdio.h>
    
    // foo() is a function that takes a pointer to an int, or simply,
    // the address of an int, passed by value
    void foo(int *p);  // I always prototype all my functions
    
    int main(void)
    {
       int a = 123; // Always initialize all your local variables,
                    // to some legitimate value, or 0!
    
       // ptr is a pointer varaible that will contain the address
       // of an int, in this case, the address of the variable, a.
       int *ptr = &a;
    
       printf("Address of a: %p\n", (void *)&a);
       printf("  Value of a: %d\n\n", a);
    
       printf("Address of ptr: %p\n", (void *)&ptr);
       printf("  Value of ptr: %p\n\n", (void *)ptr);
    
       // foo() may be called passing the address of a. An int *
       foo(&a);
    
       // Or foo() may be call with the pointer, ptr, or the address
       // value containd within ptr, the address of a, Also an int *
       foo(ptr);
    
       // foo() may NOT be called with "&ptr"!!!
       // You are attempting to pass the address of ptr, NOT the
       // address contained within ptr! &ptr is a int **,
       // A pointer to a pointer to an int!!!  Which explains the
       // warning message yopur received.
       // foo(&ptr);
    
       return 0;
    }
    
    void foo(int *p)
    {
       printf("Inside foo(), Address of the local variable, p: %p\n", (void *)&p);
       printf("Inside foo(), Address passed through p: %p\n", (void *)p);
       printf("Inside foo(), Value of value pointed to by p: %d\n\n", *p);
    }
    You really need to study one of the three books I recommended to you earlier. A good up-to-date book on C will thoroughly explain pointers, the most difficult topic in learning C, along with so much more that you need to program in C! I can't emphasize this enough!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 06-04-2013, 08:25 AM
  2. Passing Argument from incompatible pointer type
    By AmritxD in forum C Programming
    Replies: 3
    Last Post: 08-15-2010, 03:23 PM
  3. Replies: 4
    Last Post: 04-21-2008, 12:15 PM
  4. Replies: 3
    Last Post: 04-15-2008, 02:16 AM
  5. Replies: 2
    Last Post: 04-11-2008, 02:42 AM

Tags for this Thread