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" /* getrequired declarations */

void print_matrix_wrap();
void populate_matrix(Matrix * matrix);
void print_matrix(Matrix * matrix);

#endif

Leave a Reply