C Unknown type name 'my_structure' - c

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.

Related

how to use a struct defined in a certain header file from another header in C?

I have two headers files, stack.h
#ifndef __STACK_H__
#define __STACK_H__
typedef struct StackElement_
{
int value;
struct StackElement_ *next;
} StackElement, *Stack;
/*----------------------Prototypes----------------------*/
Stack new_stack();
void push_to_stack(Stack *, int);
int pop_stack(Stack *);
int peek_stack(Stack);
int stack_length(Stack);
void print_stack(Stack);
Bool is_empty_stack(Stack);
void clear_stack(Stack);
/*------------------------------------------------------*/
#endif
and utils.h
#ifndef __UTILS_H__
#define __UTILS_H__
#define INT_MIN -2147483648
/*------------------------Typedef-----------------------*/
typedef enum Boolean_ {
FALSE,
TRUE
} Bool;
/*------------------------------------------------------*/
#endif
In stack.h, I need to know Bool but when I include utils.h in stack.c, the structure is still not known in stack.h. How to do this without having to define it directly in stack.h?
You need to include utils.h in stack .h (not stack.c). The #include statements are part of the C macro language, which is a simple pre-processor. It literally takes the file given as the filename (#include filename) and inserts it into your program (during the pre-processor stage of the compile).
A source file or include file should include all files necessary.
So if stack.h is dependent on declarations in util.h, then you should #include "util.h" in stack.h. That way, any module that includes stack.h doesn't need to worry about also including util.h and putting it in the right order.
If a module decides to include both that should be fine as well. The include guards you've added should address that.
You didn't show the source of stack.c, but you most likely included stack.h before util.h. That would explain your issue since the definitions needed by stack.h appear after them instead of before.

are header guards limited to the scope of their respective library?

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;

How to use the same structure accross multiple source files?

I have 3 source files: matrix.c, tetramino.c and learntris.c (which includes the headers tetramino.h and matrix.h, linking it with the respective files). I have a structure: struct tetramino that is need in all these files. After reading this question and its answers- How to use a defined struct from another source file?, I created a header file structure.h and now my files look like this:
In structure.h:
typedef struct tetramino
{
int type;
char *p;
}tetramino;
In matrix.h:
#include"structure.h"
int print_matrix(void);
int clear_matrix(void);
In tetramino.h:
#include"structure.h"
int rotate(void);
int set_tetramino(void);
And finally, in the main learntris.c file contains:
#include"structure.h"
#include"matrix.h"
#include"tetramino.h"
Now, upon compiling them, I get these errors:
error: redefinition of 'struct tetramino'
and
error: conflicting types for 'tetramino'
Where is the problem?
When you #include <structure.h> in all of your files, it includes them each time. This causes it to try to define the structure each time.
Use include guards to ensure that the header file will be included once.
#ifndef STRUCTURE_H
#define STRUCTURE_H
typedef struct tetramino
{
int type;
char *p;
}tetramino;
#endif /* STRUCTURE_H */
It is suggested to use guards in all your header files, however this is not a must, but a very good practice.
As stated by Neroku, you could use #pragme once instead. Read more here.
Besides guards, that other answers explain, it is not good practice to include .h files in .h files as you now cannot control the order in which they are included. Also, a change to a .h file can now result in all your c files needing recompilation, even if they are not affected by the change (that is, you create unnecesary dependencies).
You should have included structure.h only in the C files and then only when the C file needs to know about the structure.
#include literally pastes the contents of the included file into the location of the #include directive. So in your example, you end up with 3 times the same structure declaration.
The canonic solution for this is guard macros:
#ifndef EXAMPLE_HEADER_FILE_H
#define EXAMPLE_HEADER_FILE_H
struct exampleStruct
{
// ...
};
#endif
This way, only the first #include will actually paste the declaration, every consecutive #include will cause the preprocessor to skip the whole header because the guard macro is already defined.
Every header file should have the following structure:
#ifndef TETRAMINO_STRUCTURE_H
#define TETRAMINO_STRUCTURE_H
struct tetramino { ... };
#endif
This means that the main part of the header file is only evaluated once. The name TETRAMINO_STRUCTURE_H consists of the project name, the file name and the trailing H, meaning header.
Second, since the function declarations don't need the tetramino type, you don't need to #include "structure.h" in them. You only need these lines in the corresponding .c files.

C header file #ifndef #include error

I'm trying to figure out, how to use C headers with #ifndef and #include.
Lets say I have these two header files:
headerA.h:
#ifndef HEADERA_H
#define HEADERA_H
#include "headerB.h"
typedef int MyInt;
TFoo foo;
... some other structures from headerB.h ...
#endif
headerB.h
#ifndef HEADERB_H
#define HEADERB_H
#include "headerA.h"
typedef struct foo{
MyInt x;
} TFoo;
#endif
headerA.c
#include "headerA.h"
... some code ...
headerB.c
#include "headerB.h"
... some code ...
When compiling headerB.c, it says
In file included from headerB.h,
from headerB.c:
headerA.h: error: unknown type name ‘MyInt’
I think, it's becouse when headerB.h is compiling, it defines HEADERB_H and then, when headerA.h wants to include headerB.h, the #ifndef HEADERA_H is false = skips including.
What is the best practice here? I just read, that best practice is to do all #include directives in header files, but in this situation it looks like a problem.
EDIT: Ok, sorry for misleading you. This is just and example from bigger project with more files.
You have a circular dependency. Header file headerA.h depends on headerB.h which depends on headerA.h and so on and on.
You need to break that dependency, for example by not including headerB.h in headerA.h. It's not needed (nothing in headerA.h needs anything from headerB.h).
If you have to include headerB.h (as stated in your recent edit) then you first should reconsider how you use your header files, and what definition you place where. Perhaps move the definition of MyInt to headerB.h? Or have more header files, like one for type-aliases (like your MyInt which I personally see no use for), one for structures and one for variable declarations?
If that's not possible then you could try by changing the order of definitions and the include, like
#ifndef HEADERA_H
#define HEADERA_H
// Define type alias first, and other things needed by headerB.h
typedef int MyInt;
// Then include the header file needing the above definitions
#include "headerB.h"
TFoo foo;
... some other structures from headerB.h ...
#endif
Just drop the line
#include "headerB.h"
from file headerA.h

How does inclusion of header file happen?

I have a plain C code with *.c and *.h files in the workspace.
I have a header file 1.h declaring some structure as
struct my1
{
int a;
..
..
}my_t;
But when i try to declare a variable of type struct my1 in another header file 2.h as follows:-
struct my1 variable1;
It gives error at this declaration point.
Looks like my1 is undefined here in 2.h file.
In file 1.h I need to include 2.h, so in file 2.h I cannot include 1.h, for fear of recursive inclusion.
My question is:-
What do i need to declare to resolve the compilation error in this case?
This whole thing made me think about further questions about header file inclusions.
How are the header files included, in what order, which header file first then which one?
Will recursive inclusion of header files cause errors one file including other and other including first?
Could not post the actual code snippets for some security reason, so sorry if the question somewhat poses some readability problems.
You should start by putting an inclusion lock in all your .h files (this is called an include guard):
#ifndef ONE_H
#define ONE_H
//rest of header
#endif //ONE_H
That way you can include it multiple times.
Second:
typedef struct my1 { int a; .. .. }my_t;
You need a typedef in C (not in C++)
The headers are included in the order of inclusion.
If you compile a file abc.c which starts with:
#include "a.h"
#include "b.h"
then a.h will be included first, then b.h.
You could think of it, as if you paste the code in the file. It is included at that point.
It's like the folks said before.
I just want to add that sometimes even #ifdef won't help you.
//file1.h
#ifndef F1
#define F1
#include "file2.h"
struct file1st {
struct file2st *ptr;
};
#endif
//file2.h
#ifndef F2
#define F2
#include "file1.h"
struct file2st {
struct file1st *ptr;
};
#endif
//main.c
#include "file1.h"
#include "file2.h"
/*
This will give you an error of **struct file1st not defined**
Let's see why:
1) file1.h is included
2) file1.h includes file2.h before it declares anything
3) the definition of struct file2st occurs and it uses struct file1st which isn't declared yet
*/
int main(int argc, char* argv[]){
struct file1st st1;
struct file2st st2;
return 0;
}
The way to work this out is:
//file1.h
#ifndef F1
#define F1
struct file2st;//just declare, it will be defined later.
struct file1st {
struct file2st *ptr; // ok, compiler KNOWS the size of struct file2st*(pointer)
struct file2st file2Var;// NOT ok, compiler doesn't know sizeof(struct file2st)
};
#endif
//file2.h
#ifndef F2
#define F2
#include "file1.h"
struct file2st {
struct file1st *ptr;
};
#endif
Header files are included in the order of include directives. Once the compiler sees an include directive it opens the file to include and simply inserts all of its contents into the including file.
If the included file has include directives inside, the same is done for them. This process continues until all of the include directives have been processed.
Only after that the compilation is started.
That's why if any file is included more than once (A included B and C; both B and C include D for example) you'll often see compiler complaining about redefinitons. To resolve this add inclusion locks (aka include guards) - the ifdef directives.
//file Header1
#ifndef Header1Guard
#define Header1Guard
// all the header text here
#endif
I second the guard suggestion.
I religiously use the following header template:
#ifndef HELLOWORLD_H_
#define HELLOWORLD_H_
// Header stuff here.
#endif // HELLOWORLD_H_
When the compiler see's an #include, it simply replaces that line with the contents of the header file (minus any processed directives in the header). So, that means you can include the file in as many places as you like without risking recursive includes.
Every header file is included in every translation unit (source file) in which there is an include directive for it. This is intended, and will happen even with inclusion guards -- every translation unit that uses your struct needs to know how that struct is defined so that it can be laid out in memory the same way throughout all the translation units of your app. The inclusion guards just prevent it from being included multiple times within one translation unit. Include files will be included in the order you include them within that translation unit (and they'll be recursively included if include files include other files... as others have said). The order of translation units being compiled is up to you (or your IDE) to specify to the compiler. It shouldn't matter what that order is, however, since every translation unit is completely independent until it gets to the linking phase of the build process.
It's been a while since I worked with C, but I think what you want to do is forward define my1.
In 2.h, try putting this near the top:
struct my1;
Sorry, I can't answer your other two questions.
// Header1.h
typedef struct tagHeader1
{
} Header1;
// Header2.h
struct Header1;
// Header2.c
#include "Header1.h"
Note: This only works for pointers (and in c++, references). If you have a reference to a complete object, the compiler will need to know about it.

Resources