0

I got the next error when I compile my project.

./PC.h:15:12: error: unknown type name 'InstructionMemory'
PC *new_pc(InstructionMemory *memoria);
           ^
./PC.h:17:1: error: unknown type name 'InstructionMemory'
InstructionMemory *get_memory(PC *programCounter);
^
2 errors generated.
In file included from main.c:5:
./InstructionRegister.h:7:36: error: unknown type name 'BankRegister'
int opera(InstructionRegister *IR, BankRegister *bank);

But this don't makes me sense, I look at the files and they are headers files, so I know that you can not use #include into headers file. So I don't know what I'm doing wrong.

There is the content of my PC.h file:

typedef struct PC PC;
PC *new_pc(InstructionMemory *memoria);
int getpc(PC *programCounter);
InstructionMemory *get_memory(PC *programCounter);
char *fecth(PC *programCounter);
char *linea_actual(PC *programCounter);

I use the next makefile to compile:

CC = gcc
CFLAGS=-I
DEPS = ALU.h InstructionRegister.h Rebasing.h BankRegister.h MemoryInstruction.h ControlUnit.h PC.h

run: exect
    ./exect $(EX)

%.o: %.c $(DEPS)
    $(CC) -c $< $(CFLAGS)

exect: ALU.c InstructionRegister.c Rebasing.c BankRegister.c MemoryInstruction.c main.c ControlUnit.c PC.c
    gcc -o exect InstructionRegister.c Rebasing.c BankRegister.c MemoryInstruction.c main.c ControlUnit.c PC.c -I.


clean:
    rm -f *.o

1 Answers1

0

so I know that you cannot use #include into headers file.

You are mistaken. You can, and often should and want to, use several include directives in your header file.

A typical small C project (e.g. less than a hundred thousands lines of C code in total) often would have a single common header file, e.g. myheader.h, typically starting with an include guard and several system includes, so like

#ifndef MYHEADER_INCLUDED
#define MYHEADER_INCLUDED

// some system includes
#include <stdio.h>
#include <stdlib.h>

/// your type declarations
enum foo_en { /* blablabla */ };
struct bar_st { /* blablabla */ };
typedef struct bar_st Bar;
/* etc... */

/// your global functions 
extern int myglobfun(int, int);
/* etc...*/

/// your global variables (have only a few of them)
extern Bar*my_bar;
/* etc... */

#endif /*MYHEADER_INCLUDED*/

This is just one possibility of organizing a project. Some people prefer to have many header files and explicitly #include system headers before some of their own headers in every of their translation units (e.g. C source files).

The advantage of having a single common header is that the Makefile is simple to code, and you might even precompile your common header. A disadvantage is that any change (e.g. adding a field in a common struct) in that header forces make to recompile everything (not a big deal for a small project).

Alternatively you could have many header files, then be sure to use include guards (in the single common header case it is actually useless but does not harm) in them, and to define a discipline regarding multiple inclusion. Often, a header file would itself include other needed header files, or else check that they have been included, e.g. with

 // file "myheaderone.h"
 #ifndef MYHEADERONE_INCLUDED

 // check that "myotherheader.h" has been included
 #ifndef MYOTHERHEADER_INCLUDED
 #error myotherheader.h should have been #include-d
 #endif

 //// etc

Alternatively you might code #include "myotherheader.h" near the beginning of myfirstheader.h

If you have multiple headers, you need a complex Makefile and you'll rather generate the dependencies, see this. It uses some preprocessor options to gcc like -M and friends.

BTW, your Makefile is wrong. Don't hardcode cc in it (but use $(CC)). Be sure to ask GCC for all warnings & debug info (e.g. CFLAGS= -Wall -g). Learn about GNU make catalog of rules by running make -p. And your CFLAGS= -I is really wrong, you might want CFLAGS= -I. -Wall -g since -I should always be followed by a directory.

PS. If using gcc take the habit of always passing -Wall to it. Very often (and certainly in your case) you also want -Wextra (to get even more warnings; remember the compiler warnings are your friends and you should improve your code till you have none of them) and probably -g (to be able to use the -g debugger). For benchmarking purposes ask the compiler to optimize (e.g. with -O1 or -O2 -mcpu=native).

Be aware of the -H preprocessor option: it is asking gcc to show every included file. Sometimes (e.g. to debug some nasty macro) you want to see the preprocessed form of a translation unit, use gcc -C -E to get it.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547