Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C: "invalid use of undefined type ‘struct X’ & dereferencing pointer to incomplete type" errors

I've been perusing similar questions to mine for a couple of days but still haven't found a solution. Thanks any any help:

I have two files, one containing methods for dealing with rational numbers and one that handles them in a 2 dimensional array. My problem is matrix.c doesn't recognize the fraction structure in contained in fraction.c. I believe my problem is somehow related to the way I declared my 2d array.

In fraction.c:

struct fraction {
   int integer;
   int num;
   int den;
};
typedef struct fraction* fractionRef;  //This line is in fraction.h

In matrix.c:

#include "fraction.h"

typedef struct matrix* matrixRef;

struct matrix {
   int rows;
   int columns;
   fractionRef *m;
}matrix;

matrixRef new_matrix ( int rows, int columns ) {
   matrixRef matrix;
   matrix = (matrixRef)malloc( sizeof( matrix ) );
   matrix->m = (fractionRef*)calloc( rows, sizeof( fractionRef ) );
   int i;
   for ( i=0; i<=rows; i++ )
     matrix->m[i] = (fractionRef)calloc( columns, sizeof( fractionRef ) );
   assert( matrix->m );
   return matrix;

}
void free_matrix ( matrixRef freeMe ) {
   if ( freeMe != NULL ){
      int i, j;
      for( i = 0; i <= freeMe->rows; i++ ){
         for ( j = 0; j <= freeMe->columns; j++ ){
            free_fraction( freeMe->m[i][j] ); //ERROR OCCURS HERE
         }
      }
      freeMe->rows = 0;
      freeMe->columns = 0;
      free(freeMe);
      freeMe = NULL;
   }
}

The error I get corresponds to the line in matrix.c I marked.

matrix.c:47: error: invalid use of undefined type ‘struct fraction’
matrix.c:47: error: dereferencing pointer to incomplete type

This is probably all because I learned java BEFORE c, big mistake!!! Thanks again for any help.

EDIT: Thanks everyone. So the way I see it now is everything in the header .h files are similar to public in java. My fraction struct definition wasn't "public" to the c compiler so my matrix.c wasn't able to access it.

like image 368
stewartbracken Avatar asked May 09 '11 22:05

stewartbracken


2 Answers

You must move the definition of the struct into the fraction.h file. Unlike Java, the compiler and linker do not "magically" cause one .c file to reference information inside another .c file. (It could be done if you #include one .c file in another -- a bad idea.)

The directive

#include "fraction.h"

causes the text contents of the header file to be placed, as if by cut-and-paste, at the line with that directive. The compiler processes one input file at a time, reading in the #include'd files, and all the needed information must be present while that one .c file is compiled.

To help with your understanding, I will point out a terrible way to accomplish what you require: simply cut-and-paste the struct definition of struct fraction into the top of matrix.c, immediately prior to #include "fraction.h" -- the result will compile. In Java, the compiler might complain that you have declared some duplicate types. In C, what you've done is define two different structs, which happen to have an identical memory layout and the same name. Only the same memory layout is needed to make them interchangable from the perspective of linking together object files.

Yes, this is a misunderstanding you picked up from Java. It's wonderful that you are learning C!

like image 132
Heath Hunnicutt Avatar answered Oct 19 '22 23:10

Heath Hunnicutt


Move the struct fraction definition to "fraction.h" and

#include "fraction.h"

in both "fraction.c" and "matrix.c"

like image 41
pmg Avatar answered Oct 20 '22 00:10

pmg