help with header files in C
Ok, I have a pretty good understanding of how header files are to be used in C programs but I keep having this problem that I can't seem to get around. Here is the situation:
Device.c contains #include "Device.h"
Device.h contains a definition for a struct and the following...
#ifndef DEVICE_H
#define DEVICE_H
#include "SubDevice.h"
typedef struct {
subDevice * subDevice1;
subDevice * subDevice2;
} device;
#endif
SubDevice.c contains #include SubDevice.h
SubDevice.h contains the definition of the subDevice struct and the following...
#ifndef SUBDEVICE_H
#define SUBDEVICE_H
#include "Device.h"
typedef struct{
int MyInt;
double MyDouble;
}subDevice;
#endif
The problem is that I get a compiler error in Device.h in my struct definition. At the line subDevice * subDevice1;
it says syntax error before subDevice
.
Is the problem that I am including the header file of the other file in each file? I thought the #ifndef - #define statements would p开发者_Go百科revent that from causing a problem...
It's not a header problem. There is a problem on one typedef
you have in SubDevice.h
. So, do change:
typedef struct{
int MyInt;
double MyDouble;
}
To:
typedef struct{
int MyInt;
double MyDouble;
} subDevice;
Your problem should be gone.
You must put a semicolon after the declaration of a struct
, and your typedef
is missing the second parameter.
EDIT to reflect OP's edit
You're including DEVICE_H
, which is an macro.
You need to include "device.h"
:
#include "device.h"
The problem is that you have a circular reference.
I guess your main file looks something like this:
#include "Subdevice.h"
#include "Device.h"
int main() {}
Because of how the C preprocessor works (and how you use the include guards), the contents of Device.h
will be read before Subdevice.h
, meaning that the subDevice
struct has yet to be defined when you define the device
struct.
Remove the #include "Device.h"
from Subdevice.h
and it should compile OK.
You have "typedef struct {...}" in your subdevice.h, when you should have "typedef struct {...} subDevice;"
The line "#include DEVICE_H" also looks somewhat wrong. Did you mean #include "device.h"?
What you seem to be missing is a good understanding of the compilation model used by C (and C++) compilers.
Compiling a C or C++ source file can be separated in three stages:
- Preprocessing
- Compiling
- Linking
Preprocessing
During preprocessing, the compiler (or separate preprocessor) goes over the source file and performs macro expansion and #include
replacements.
All #include
directives are replaced by the contents of the referenced file.
All macro definitions are processed and where a macro invocation occurs in the text, it is substituted with the replacement text. This is a completely textual process.
After preprocessing, there are no preprocessor directives (lines starting with a #
) left in the source code
Compiling
During compilation, the compiler interprets the source code according to the rules of the C (or C++) language and translates the code to object code.
Linking
During the linking phase, all object files are combined together and linked with the relevant libraries to create an executable.
The source code presented here has two problems:
- The subdevice.h file contains a spurious
#include DEVICE_H
directive. This should be reported by the preprocessor/compiler, becauseDEVICE_H
does not resolve to a filename in quotes or angle-brackets. - There is a missing semi-colon (
;
) (and a missing typedef name) at the end of the typedef in subdevice.h. As a result, the compiler tries to combine this with the next lines of code it sees (thetypedef struct
in device.h) and gets terribly confused. This triggers the syntax error message.
One good way of debugging your code with preprocessor errors is to gcc -E <files>
, so that you can actually see what would your program look like after that preprocessor is done with it.
精彩评论