Thread: Dereferencing pointer to incomplete type

  1. #1
    Registered User
    Join Date
    Sep 2015
    Posts
    9

    Dereferencing pointer to incomplete type

    Just trying to figure out why I would need to define struct point a second time in main.c in order to remove the dereferencing pointer to incomplete type error I am having in main.c?

    Am I tackling this all wrong?

    point.h
    Code:
       typedef struct point* point_t;
    
       point_t create_point();
    point.c
    Code:
        #include <point.h>
    
        struct point{
             int x;
             int y;
        };
    
       point_t create_point(){
    
           point_t p = malloc(sizeof(point_t));
           p->x = 10;
    
           printf("%d\n", p->x); // fine prints 10
    
          return p; 
       }
    main.c
    Code:
        #include "point.h"
    
        int main(void){
    
            point_t my_point = create_point();
    
            // Dereferencing pointer to incomplete type
            printf("%d\n", my_point->x);
    
           return 0;
        }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    main.c doesn't know about
    Code:
        struct point{
             int x;
             int y;
        };
    because it's in point.c

    You can either
    1. move the struct declaration to point.h

    2. provide an access function to return the value of x

    Eg
    Code:
    int pointGetX( point_t p ) {
      return p->x;
    }
    Put that code in point.c, and put a prototype for the function in point.h
    main.c would become
    printf("%d\n", pointGetX(my_point));
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    In your header, you declared point_t to be an opaque pointer type. This means that you only say that it is a pointer type such that a pointer of this type points to a struct point, but the definition of struct point is not provided. Therefore, a pointer of this type cannot be dereferenced without separately providing the definition of struct point. Rather, you probably should have written:
    Code:
    #ifndef EP_POINT_H_
    #define EP_POINT_H_
    
    struct point {
        int x;
        int y;
    };
     
    struct point *create_point(void);
    
    #endif
    Notice that:
    • I included the header inclusion guards, without which including point.h twice in the same translation unit (source file + headers) would result in a multiple definition of struct point, which would be an error.
    • I got rid of point_t. Unless you want to go with an opaque pointer, explicitly having the pointer notation is better as it reminds the reader that a pointer that can be dereferenced is involved.
    • I explicitly used void as the parameter list for the declaration of create_point. Without this, the declaration says nothing about the parameters of create_point.

    In your source files, you should #include "point.h", not <point.h>. The latter is generally for standard headers, other headers provided by the implementation, and headers from external libraries that you installed.

    Of course, you might decide that you actually do want an opaque pointer. If so, you could do something like this:
    Code:
    #ifndef EP_POINT_H_
    #define EP_POINT_H_
    
    typedef struct point* point_t;
     
    point_t point_create(void);
    void point_destroy(point_t point);
    int point_get_x(point_t point);
    int point_get_y(point_t point);
    
    #endif
    Then in the source file:
    Code:
    #include "point.h"
    
    struct point {
        int x;
        int y;
    };
    
    /* ... */
    
    int point_get_x(point_t point) {
        return point->x;
    }
    Now, you could write:
    Code:
    #include <stdio.h>
    #include "point.h"
    
    int main(void) {
        point_t my_point = point_create();
        printf("%d\n", point_get_x(my_point));
        point_destroy(my_point);
    
        return 0;
    }
    The dereferencing happens in point_get_x. At that point, the definition of struct point is available, so there is no incomplete type error. The useful part of doing this is that it means that at some later date, you could change the definition of struct point, e.g., rename x to x_coordinate, and the code in main does not need to change.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Registered User
    Join Date
    Sep 2015
    Posts
    9
    Aha, so its only the definitions in .h files that are "exposed" to main.c?
    Actually, that makes a lot of sense because I wanted to remove direct access to the structs members directly... Using an accessor function is exactly what I was after. Just couldn't wrap my head around how to pull in the struct

    @laserlight - Thanks for all those little tips in the "Notice that" bullet points.
    Last edited by elementary_peng; 01-22-2016 at 07:04 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. dereferencing pointer to incomplete type
    By jeltedeproft in forum C Programming
    Replies: 2
    Last Post: 12-14-2015, 07:57 AM
  2. Another 'dereferencing pointer to incomplete type'
    By thealmightyone in forum C Programming
    Replies: 7
    Last Post: 11-25-2010, 08:49 PM
  3. dereferencing pointer to incomplete type
    By SasDutta in forum C Programming
    Replies: 2
    Last Post: 07-28-2010, 09:32 AM
  4. dereferencing pointer to incomplete type
    By johnny_ in forum C Programming
    Replies: 4
    Last Post: 03-01-2010, 10:46 AM
  5. dereferencing pointer to incomplete type
    By kataya in forum C Programming
    Replies: 2
    Last Post: 04-16-2008, 01:37 AM