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)
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