Search code examples
cfilestructbuildtypedef

Using a struct defined in a header file in different source (.c) files


I have a program which has several files as follows: main.c, functions.c, functions.h, matrix.c, matrix.h. main.c is the main file. Inside functions.c there is a function which uses the struct matrix which is defined in matrix.h.

If I compile the code I get the following error message:

gcc  -c main.c
In file included from main.c:3:
./functions.h:4:22: error: unknown type name 'Matrix'
void populate_matrix(Matrix * matrix);
                     ^
./functions.h:5:19: error: unknown type name 'Matrix'
void print_matrix(Matrix * matrix);
                  ^
2 errors generated.
make: *** [main.o] Error 1

How is it possible to make the program run?

Here is are the source files:

//main.c
#include <stdio.h>
#include "functions.h"

int main()
{
  print_matrix_wrap();
  return 0;
}
//functions.c
#include <stdio.h>
#include <stdlib.h>
#include "functions.h"
#include "matrix.h"


void print_matrix_wrap()
{
  size_t ncol = 4;
  size_t nrow = 4;
  Matrix *mat1 = (Matrix *) calloc(1, sizeof(Matrix));
  
  if (mat1 == NULL) { printf("Could not allocate memory\n"); exit(EXIT_FAILURE); }
  mat1->nrows = nrow;
  mat1->ncols = ncol;
  mat1->array = (int *) calloc(mat1->nrows * mat1->ncols, sizeof(*mat1->array));
  if (mat1->array == NULL) { printf("Could not allocate memory\n"); exit(EXIT_FAILURE); }

  populate_matrix(mat1);
  print_matrix(mat1);
}

void populate_matrix(Matrix * matrix)
{
  matrix->array[0 * matrix->ncols + 0] = 2;
  matrix->array[0 * matrix->ncols + 1] = 3;
  matrix->array[0 * matrix->ncols + 2] = 4;
  matrix->array[0 * matrix->ncols + 3] = 10;
  matrix->array[1 * matrix->ncols + 0] = 3;
  matrix->array[1 * matrix->ncols + 1] = 4;
  matrix->array[1 * matrix->ncols + 2] = 10;
  matrix->array[1 * matrix->ncols + 3] = 8;
  matrix->array[2 * matrix->ncols + 0] = 10;
  matrix->array[2 * matrix->ncols + 1] = 5;
  matrix->array[2 * matrix->ncols + 2] = 6;
  matrix->array[2 * matrix->ncols + 3] = 4;
  matrix->array[3 * matrix->ncols + 0] = 9;
  matrix->array[3 * matrix->ncols + 1] = 10;
  matrix->array[3 * matrix->ncols + 2] = 1;
  matrix->array[3 * matrix->ncols + 3] = 9;
}


void print_matrix(Matrix * matrix)
{
  for (size_t row =0; row<matrix->nrows; row++)
  {
    for (size_t col =0; col<matrix->ncols; col++)
    {
      printf("%3d ", matrix->array[row * matrix->ncols + col]);
    }
    printf("\n");
  }
}
//functions.h

void print_matrix_wrap();
void populate_matrix(Matrix * matrix);
void print_matrix(Matrix * matrix);
//matrix.c
#include <stdio.h>
#include <stdlib.h>
#include "matrix.h"

void print_matrix(Matrix * matrix)
{
  for (size_t row =0; row<matrix->nrows; row++)
  {
    for (size_t col =0; col<matrix->ncols; col++)
    {
      printf("%3d ", matrix->array[row * matrix->ncols + col]);
    }
    printf("\n");
  }
}
//matrix.h
typedef struct {
  size_t nrows, ncols;
  int *array;
} Matrix ;

void print_matrix(Matrix * matrix);
#makefile

CC = gcc 
CFLAGS = -Wextra -Wall -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wcast-align -Wstrict-prototypes -Wstrict-overflow=5 -Wwrite-strings -Waggregate-return -Wcast-qual -Wswitch-default -Wswitch-enum -Wconversion -Wunreachable-code -pedantic -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition

BINC=main

allc: $(BINC) 

$(BINC): $(BINC).o functions.o matrix.o
    $(CC) $(CFLAGS) $(BINC).o functions.o -o $(BINC)

$(BINC).o: $(BINC).c
    $(CC) -c $(BINC).c

functions.o: functions.c functions.h 
    $(CC) -c functions.c

matrix.o: matrix.c matrix.h 
    $(CC) -c matrix.c

clean:
    $(RM) -rf $(BINC) *.dSYM *.o

runc: allc
    ./$(BINC)

Solution

  • Use #include in the header files to get required declarations.

    Add include guards to avoid multiple declaration errors.

    //matrix.h
    #ifndef MATRIX_H /* include guard */
    #define MATRIX_H
    
    typedef struct {
      size_t nrows, ncols;
      int *array;
    } Matrix ;
    
    void print_matrix(Matrix * matrix);
    
    #endif
    
    //functions.h
    #ifndef FUNCTIONS_H /* include guard */
    #define FUNCTIONS_H
    
    #include "matrix.h" /* get required declarations */
    
    void print_matrix_wrap();
    void populate_matrix(Matrix * matrix);
    void print_matrix(Matrix * matrix);
    
    #endif