I receive this error when compiling my code and got absolutely no idea after trying out for an hour.
This is the file which causes the error os_memory_strategies.h:
#ifndef _OS_MEMORY_STRATEGIES_H
#define _OS_MEMORY_STRATEGIES_H
#include "os_mem_drivers.h"
#include "os_memheap_drivers.h"
#include "os_process.h"
#include "defines.h"
#include <stdint.h>
MemAddr os_Memory_FirstFit (Heap *heap, uint16_t size);
#endif
The line
MemAddr os_Memory_FirstFit (Heap *heap, uint16_t size);
causes the error. As I understand "Heap" is unknown to this point. The struct Heap is defined in os_memheap_drivers.h which is included here. The struct looks like this:
typedef struct Heap{
prog_char *const name;
MemDriver *const driver;
AllocStrategy allocStrat;
Memory const memory;
}Heap;
Using AVRStudio and all the files are in the same directory.
The most typical reason for this is circular header inclusion. You include os_memheap_drivers.h into your os_memory_strategies.h (as we can see above). But apparently you also directly or indirectly include os_memory_strategies.h into os_memheap_drivers.h as well.
The include guards will naturally "resolve" this circular inclusion is some unpredictable way, i.e. one of these files will end up being included first and the other will end up being included second. In your case os_memory_strategies.h ended up being included first, which is why it does not recognize Heap as type name.
Circular header inclusion never works and never achieves anything. Get rid of it, i.e. make sure os_memory_strategies.h in not included into os_memheap_drivers.h.
Related
I've inherited some code* which declares and defines a struct in a header file (a_A.h). This struct is in the top file of an include hierarchy tree which symbolically looks like:
file: t_T.h (#includes "c_C.h") //defines a struct
file: c_C.h (#includes "h_H.h")
file: h_H.h (#includes "a_C.h")
file: a_C.h (#includes <stdio.h>)
Each header has the appropriate header guards and appear to be non-recursive when looked at as a flat collection of files. However, files c_C.h and a_C.h reside in the same library. While h_H.h resides in a different library. From a library perspective this symbolically appears as:
t_T.h (includes a file from Lib_C)
Lib_C: (includes a file from Lib_H)
Lib_H (includes a file from Lib_C)
which is recursive and is the likely cause of redefinition problems when I compile the code (the linker complains that the struct in file a_C.h is redefined).
1) Did I correctly identify the issue?
2) If so, why? I am guessing that linked objects in a library appear flat to the linker (i.e. they've lost their hierarchy context). And if guessed somewhat correctly then:
3) Should I consider header guards to be limited to the scope of their respective library?
Below is the error statement from the problems window:
symbol "ov5642_1280x960_RAW" redefined: first defined in "./TakePhoto.obj"; redefined in "./ArduCam/ov5642_Config.obj"
Header in ./TakePhoto:
#ifndef TAKEPHOTO_H
#define TAKEPHOTO_H
#include "ov5642_Config.h"
#include "HAL_ArduCAM.h"
...
#endif /* TAKEPHOTO_H_ */
Header in ./ArduCAM/ov5642_Config.h:
#ifndef ARDUCAM_OV5642_CONFIG_H_
#define ARDUCAM_OV5642_CONFIG_H_
#include "HAL_ArduCAM.h"
#include "ov5642_Sensor_Values.h"
....
#endif /* ARDUCAM_OV5642_CONFIG_H_ */
Header in HAL_ArduCAM
#ifndef HAL_ArduCAM_h
#define HAL_ArduCAM_h
#include <stdint.h>
#include "driverlib.h"
....
#endif /* HAL_ArduCAM_h */
ov5642_Sensor_Values.h has the following
#ifndef ARDUCAM_OV5642_SENSOR_VALUES_H_
#define ARDUCAM_OV5642_SENSOR_VALUES_H_
#include <stdint.h>
const struct sensor_reg ov5642_1280x960_RAW[] =
{
{0x3103,0x93},
{0x3008,0x02},
{0x3017,0x7f},
.....
#endif /* ARDUCAM_OV5642_SENSOR_VALUES_H_ */
It seems that the contents of OV5642_Sensor_Values is copied twice, once for TakePhoto and once again for ovV5642_Config despite their header guards. My original thought was that there was a recursive dependencies but didn't find it.
Ok, I've made an example pasted below. There are five files in this example, three files (bar.h, foo.h, foo.c reside in a library), the other two files (foo1.h, foo1.c) do not. Notice that foo.h includes bar.h and that foo1 includes both foo.h and bar.h.
I am conjecturing that the guard headers of bar.h are not preserved when the pre-processor copies into foo.h. Thus when foo1 includes bar.h and foo.h the symbol redefinition arises. So to answer my own question, no, it is not a library issue. Not preserving the header guard seems the likely cause of my problem.
They are pasted below.
/*
* bar.h
*
*/
#ifndef ARDUCAM_BAR_H_
#define ARDUCAM_BAR_H_
#include <stdint.h>
typedef struct regStruct {
uint16_t reg;
uint8_t val;
} regStruct;
const struct regStruct regArray[] =
{
{0x3103,0x03},
{0x3104,0x03},
{0x3008,0x82},
{0xffff,0xff},
};
const struct regStruct tinyArray[] =
{
{0x3106,0x03},
{0x3003,0x82},
{0xffff,0xff},
};
#endif /* ARDUCAM_BAR_H_ */
/*
* foo.h
*
*
*/
#ifndef ARDUCAM_FOO_H_
#define ARDUCAM_FOO_H_
#include <stdint.h>
#include <stdio.h>
#include "bar.h" //including this file causes redefinition
typedef struct Init_Parameters {
//! Select sensor resolution
//! options.
//! \n Valid values are:
//! - \b big
//! - \b small
//! - \b tiny
uint8_t size;
} Init_Parameters;
uint8_t Sensor_Init(Init_Parameters *param);
typedef enum {
small=0,
big,
tiny
} select_size;
#endif /* ARDUCAM_FOO_H_ */
/*
* foo.c
*
*
*/
#include "foo.h"
uint8_t Sensor_Init(Init_Parameters *param)
{
switch(param->size)
{
case big:
break;
case small:
break;
case tiny:
break;
}
return 0x01;
}
/*
* foo1.h
*
* Created on: Feb 28, 2019
* Author: jnadi
*/
#ifndef FOO1_H_
#define FOO1_H_
#include "foo.h"
#include "bar.h"
#endif /* FOO1_H_ */
/*
* foo1.c
*
* Created on: Feb 28, 2019
* Author: jnadi
*/
#include "foo1.h"
void Camera_Init(){
Init_Parameters setParams; //create instance
setParams.size=big;
Sensor_Init(&setParams);
}
The physical locations of header files affect C source compilation only via the include-file search path. Headers have to be in one of the directories that are searched, and if there is more than one with the same name, then the search path order determines which is used. The association, if any, between a given header and a library is not known to the compiler, and it does not affect compilation, unless indirectly via the search path.
Your claim that
the linker complains that the struct in file a_C.h is redefined
(emphasis added) makes sense only if by "the struct" you mean an object of a structure type. The linker may complain if a variable with external linkage is defined in more than one translation unit, which will likely happen if a header contains a definition of that variable (as opposed to merely a declaration).
If instead the issue is that the structure type is redefined, then that would be diagnosed by the compiler, not the linker, and it would tend to contradict your conclusion that
Each header has the appropriate header guards
. Proper header guards are exactly what would prevent such a type redefinition issue.
1) Did I correctly identify the issue?
Not with any specificity, for sure. That there are header dependencies in both directions between headers associated with different libraries reflects poor design, but it would not inherently cause compilation or linking to fail.
2) If so [...]
N/A
3) Should I consider header guards to be limited to the scope of their
respective library?
No. Header guards are relevant at the compilation stage only, and C compilation knows nothing about libraries. All header files processed by the compiler in the course of translating a single translation unit are on equal footing. In fact, the main risk in this area is in the opposite direction: a collision of header guards.
That answers the question as posed. As for what the true nature of your build issue may be, you have not given us enough information to do more than speculate. My own speculations are already conveyed above.
Using the five files posted above and commenting out an #includes bar.h in foo.h, I believe I found the answer to my problem.
The simple answer is that header guards are not preserved once it is included into the header of another file.
When bar.h is included into another header file, its header guards are superseded by the header guards of its new host (foo.h). Thus symbol redefinition issues arise when foo1.h includes both bar.h and foo.h
Header guards only prevent a .h file from including its contents twice or more within one top-level translation unit. They are to deal with cases like this, where two or more headers need to include the same set of common definitions:
// A.h
struct A { int x, y, z; };
// B.h
#include "A.h"
struct B { struct A aye; float f, g; };
// C.h
#include "A.h"
struct C { struct A aye; long l, m; };
// main.c
#include "B.h"
#include "C.h" // error, redefinition of struct A
But each translation unit starts out with a clean macro environment, so if you include a header file in two different top-level translation units, that header's declarations are made visible (once) to each. And that's what you want. (Think about standard library headers. You wouldn't want stdio.h not to declare printf in bar.c just because there existed foo.c in the same project that also included stdio.h.)
Now, your problem is that ov5642_Sensor_Values.h defines a data object (not a type), ov5642_1280x960_RAW, and this header is included into two different top-level translation units (.c source files). Each translation unit produces an object file containing a definition of ov5642_1280x960_RAW, and you get a multiple definition error from the linker when you try to combine them.
The bug causing this problem is not that ov5642_Sensor_Values.h's header guards are ineffective. The bug is that ov5642_Sensor_Values.h should not be making any global definitions. Header files should only declare things (with rare exceptions that you shouldn't worry about until you encounter them).
To fix the bug, change ov5642_Sensor_Values.h to declare ov5642_1280x960_RAW but not define it, like this:
#ifndef ARDUCAM_OV5642_SENSOR_VALUES_H_
#define ARDUCAM_OV5642_SENSOR_VALUES_H_
#include <stdint.h>
#include "sensor_reg.h"
extern const struct sensor_reg ov5642_1280x960_RAW[];
#endif
and create a new file named ov5642_Sensor_Values.c that contains the initialized definition:
#include "ov5642_Sensor_Values.h"
extern const struct sensor_reg ov5642_1280x960_RAW[] =
{
{0x3103,0x93},
{0x3008,0x02},
{0x3017,0x7f},
.....
};
and add that file to your link.
thank you everyone especially John, Zwoi. I was up against a deadline (this was inherited code) but was able to calm myself down enough to figure out what John was saying. I moved the struct definition into a c file and used an extern pointer in the header which is similar to zwoi's declaration. I am also relieved that what I did matched zwoi's example (thank you so much!).
extern const struct sensor_reg * ov5642_1280x960_RAW;
I'm trying to make a test program that simply searches for any file in its root folder:
#include <stdio.h>
#include <dir.h>
#include <dos.h>
struct ffblk ffblk;
int main(){
int result = findfirst("*.*", &ffblk,FA_ARCH);
return 0;
}
But when the code compiles, the ffblk struct declaration returns the error:
storage size of ffblk isn't known
and the findfirst() function returns:
warning: implicit declaration of function 'findfirst'[-Wimplicit-function-declaration]
as seen in this image, even though both findfirst and ffblk are members of dir.h, which is already included. I'm using Visual Studio and compiling with GCC. Does someone know what is wrong with the code, or the header files?
You really, really shouldn't be using obsolete APIs from obsolete headers like "dos.h" if you can at all avoid it. Honest!
Nevertheless, if you insist...
As dbush pointed out, the actual (obsolete!) API is _findfirst (not findfirst).
It is documented here
You'll see that the argument for this (again - OBSOLETE) API is struct _finddata_t *fileinfo (not struct ffblk).
Change your code, and everything should compile and run.
Better, change your headers (to "io.h" and "dir.h") - and the original code should probably compile and run.
I have this code:
main.h
#ifndef MAINH
#define MAINH
...
#include "my_struct.h"
void some_func(my_structure *x);
...
#endif
and
my_struct.h
#ifndef UTILSH
#define UTILSH
...
#include "main.h"
...
typedef struct abcd {
int a;
} my_structure;
...
#endif
but I'm getting this when I try to compile: error: unknown type name ‘my_structure’
Any idea why?
Because of how you've ordered your includes, the compiler sees void some_func(my_structure *x); before it sees typedef struct abcd { int a; } my_structure;.
Let's walk this through.
Assuming my_struct.h is processed first, we get the following sequence of events:
UTILSH is defined
MAINH is defined
Because UTILSH is already defined, we don't process my_struct.h again, so the typedef isn't processed
void some_func(my_structure *x); is processed.
Now the typedef is processed.
So after preprocessing, your compiler sees the following sequence of declarations:
...
void some_func(my_structure *x);
...
typedef struct abcd {...} my_structure;
Bad juju. You either need a forward declaration of my_structure in main.h, or you need to break that circular dependency (which is the much preferred option). Is there anything in main.h that my_structure.h actually uses? If so, you will want to factor it out into a separate file that both main.h and my_structure.h include.
You created a circular header inclusion. Circular inclusion never achieves anything. It is infinite. The #ifndef include guard will break the infinite inclusion circle at some unpredictable point (depending on which header is included into .c file first). This is what happened in your case. Basically, your circular inclusion got "resolved" into including main.h first and my_struct.h second. This is why main.h knows nothing about my_struct type.
Again, circular inclusion never achieves anything. Get rid of circular inclusion. Design your header structure hierarchically: lower-level headers included into higher-level headers, but never the other way around. In your case my_struct.h is probably a lower-level header, which means that you have to stop including main.h into my_struct.h. Redesign your headers so that my_struct.h no longer needs main.h.
The error message is coming from main.h while it's included in my_struct.h, before my_structure is defined. You should rethink your include paths since main.h and my_struct.h include each other.
You probably want your main.h file to just include my_struct.h, and not have my_struct.h to include anything. You're essentially instructing your C compiler to have an infinite co-include loop.
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 prevent 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, because DEVICE_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 (the typedef 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.
I'm just getting started with modular programming in C. I think I'm doing something wrong with the inclusions, because I'm getting a lot of conflicting types for 'functionName' and previous declaration of 'functionName' was here errors. I did put inclusion guards in place.
Do you know a clear tutorial that explains modular programming in C, especially how the inclusions work?
Update: I have tried to isolate my issue. Here's some code, as requested.
Update 2: updated code is below. The errors have been updated, too.
/*
* main.c
*/
#include <stdio.h>
#include "aStruct.h"
int main() {
aStruct asTest = createStruct();
return 0;
}
/*
* aStruct.h
*/
#ifndef ASTRUCT_H_
#define ASTRUCT_H_
struct aStruct {
int value1;
int value2;
struct smallerStruct ssTest;
};
typedef struct aStruct aStruct;
aStruct createStruct();
#endif /* ASTRUCT_H_ */
/*
* smallerStruct.h
*/
#ifndef SMALLERSTRUCT_H_
#define SMALLERSTRUCT_H_
struct smallerStruct {
int value3;
};
typedef struct smallerStruct smallerStruct;
smallerStruct createSmallerStruct();
#endif /* SMALLERSTRUCT_H_ */
/*
* aStruct.c
*/
#include <stdio.h>
#include "smallerStruct.h"
#include "aStruct.h"
aStruct createStruct() {
aStruct asOutput;
printf("This makes sure that this code depends on stdio.h, just to make sure I know where the inclusion directive should go (main.c or aStruct.c).\n");
asOutput.value1 = 5;
asOutput.value2 = 5;
asOutput.ssTest = createSmallerStruct();
return asOutput;
}
/*
* smallerStruct.c
*/
#include <stdio.h>
#include "smallerStruct.h"
smallerStruct createSmallerStruct() {
smallerStruct ssOutput;
ssOutput.value3 = 41;
return ssOutput;
}
This generates the following error messages:
At aStruct.h:10
field 'ssTest' has incomplete type
At main.c:8
unused variable `asTest' (this one makes sense)
The base of inclusion is to make sure that your headers are included only once. This is usually performed with a sequence like this one:
/* header.h */
#ifndef header_h_
#define header_h_
/* Your code here ... */
#endif /* header_h_ */
The second point is to take care of possible name conflicts by handling manually pseudo namespaces with prefixes.
Then put in your headers only function declarations of public API. This may imply to add typedefs and enums. Avoid as much as possible to include constant and variable declarations: prefer accessor functions.
Another rule is to never include .c files, only .h. This is the very point of modularity: a given module dependant of another module needs only to know its interface, not its implementation.
A for your specific problem, aStruct.h uses struct smallerStruct but knows nothing about it, in particular its size for being able to allocate an aStruct variable. aStruct.h needs to include smallerStruct.h. Including smallerStruct.h before aStruct.h in main.c doesn't solve the issue when compiling aStruct.c.
The multiple definition problem is most likely coming from the way you're including the code. You are using #include "aStruct.c" as opposed to #include "aStruct.h". I suspect you are also compiling the .c files into your project in addition to the #include. This causes the compiler to become confused due to the multiple definitions of the same function.
If you change the #include to #include "aStruct.h" and make sure the three source files are compiled and linked together, the error should go away.
Such errors mean that function declaration (return type or parameter count/types) differs from other function declarations or function definition.
previous declaration message points you to the conflicting declaration.