Consider the following typedef struct in C:
21:typedef struct source{
22: double ds; //ray step
23: double rx,zx; //source coords
24: double rbox1, rbox2; //the box that limits the range of the rays
25: double freqx; //source frequency
26: int64_t nThetas; //number of launching angles
27: double theta1, thetaN; //first and last launching angle
28:}source_t;
I get the error:
globals.h:21: error: redefinition of 'struct source'
globals.h:28: error: conflicting types for 'source_t'
globals.h:28: note: previous declaration of 'source_t' was here
I've tried using other formats for this definition:
struct source{
...
};
typedef struct source source_t;
and
typedef struct{
...
}source_t;
Which both return the same error.
Why does this happen? it looks perfectly right to me.
Are you sure you didn't include your header twice (without using #ifndef/#pragma once to avoid that)?
Even if there'd been some mistake in your construct it shouldn't trigger the error "redefinition of '...'" cause it's the very first line?
The most likely cause is that your header file is being included more than once.
You need to ensure that if this happens, the typedef is only executed once.
You can do this by wrapping globals.h with:
#ifndef _globals_h_
#define _globals_h_
[...]
#endif
The errors say a struct source has been defined more than once.
Maybe you included the header file twice?
Just to be on the safe side, be sure that your header gets only included once: put
#ifndef YOUR_HEADER_FILE_NAME
#define YOUR_HEADER_FILE_NAME
at the beginning, and
#endif
at the end of your header file: this will prevent it to be included twice or more by any source file.
Related
I've been developing in C using eclipse as my IDE in my virtual machine with ubuntu, I've made some progress and I wanted to test them in the real product which is an embedded system using powerpc.
In order to compile that program for our product I use Code::Blocks in Windows but the compiler is a powerpc version of the gcc.
The same code is giving me an error in the powerpc version that doesn't appear in the ubuntu version.
I have two header files gral.h and module_hand.h as follows:
The gral.h file:
#ifndef HEADERS_GRAL_H_
#define HEADERS_GRAL_H_
#include "module_hand.h"
typedef struct PROFILE
{
module_t mod; // this one comes from module_hand.h
int var1; // some other random variables
} profile_t;
#endif /* HEADERS_GRAL_H_ */
The module_hand.h is defined as follows
#ifndef HEADERS_MODULE_HAND_H_
#define HEADERS_MODULE_HAND_H_
#include <stdint.h>
#include "gral.h"
typedef struct PROFILE profile_t;
typedef struct module
{
char name[30]; // name of module
char rev[30]; // module revision
char mfr[30]; // manufacturer
} module_t;
int Mod_Init(profile_t *profile);
/* some other random functions */
#endif /* HEADERS_MODULE_HAND_H_*/
As you'll see, I don't use the PROFILE struct in the module struct, But I declare it forward to use it in the declaration of the Mod_Init function
This gives me a Error: redefinition of typedef 'profile_t'
and error: previous declaration of 'profile_t' was here
If I remove the forward declaration the error is Error: parse error before '*' token
where the line number is the line of the function declaration.
My doubt is what am I missing, and why gcc in Ubuntu does compile it with no problem.
Your powerpc compiler is enforcing the C99 rule that
If an identifier has no linkage, there shall be no more than one
declaration of the identifier (in a declarator or type specifier) with
the same scope and in the same name space, except for tags as
specified in 6.7.2.3.
(C99 6.7/3)
Your Linux compiler is observing the relaxed version of that rule that was introduced in C11:
If an identifier has no linkage, there shall be no more than one
declaration of the identifier (in a declarator or type specifier) with
the same scope and in the same name space, except that:
a typedef name may be redefined to denote the same type as it currently does, provided that type is not a variably modified type;
tags may be redeclared as specified in 6.7.2.3.
(C11 6.7/3; also C17 6.7/3)
Supposing that the compilation options are the same, the behavior difference surely arises from using different versions of GCC. More recent versions default to more recent versions of the language.
You could try adding -std=gnu11 or -std=c11 to the command-line options (for both targets) to try to get consistency. If your powerpc version of GCC is too old to accept those then you really need to update to a newer version.
Note also, however, that you don't need to have this problem in the first place. Given that module_hand.h includes gral.h, the former has no need whatever to redefine a typedef that the latter already defines.
Moreover, the fact that these two headers each include the other is a strong suggestion that they ought to be combined into one. Multiple-inclusion guards prevent an actual loop, but they are not an adequate solution.
In the gral.h header file, you define profile_t using typedef, then you redefine profile_t with another typedef in module_hand.h. You should just define the struct PROFILE in gral_h and include gral.h in module_hand.h.
gral.h:
#ifndef HEADERS_GRAL_H_
#define HEADERS_GRAL_H_
#include "module_hand.h"
typedef struct PROFILE {
module_t mod; // this one comes from module_hand.h
int var1; // some other random variables
} profile_t;
#endif /* HEADERS_GRAL_H_ */:
module_hand.h:
#ifndef HEADERS_MODULE_HAND_H_
#define HEADERS_MODULE_HAND_H_
#include <stdint.h>
typedef struct module
{
char name[30]; // name of module
char rev[30]; // module revision
char mfr[30]; // manufacturer
} module_t;
int Mod_Init(struct PROFILE *profile);
/* some other random functions */
#endif /* HEADERS_MODULE_HAND_H_*/
Well I read your answers and comments and decided to try another approach.
As some of you said, I had some kind of recursion, I wanted to keep every structure within its respective header file, but now, I dropped the idea and merged the structures in one file only.
My new approach:
Gral.h
#ifndef HEADERS_GRAL_H_
#define HEADERS_GRAL_H_
typedef struct module
{
char name[30]; // name of module
char rev[30]; // module revision
char mfr[30]; // manufacturer
} module_t;
typedef struct PROFILE {
module_t mod; // this one comes from module_hand.h
int var1; // some other variables
} profile_t;
#endif /* HEADERS_GRAL_H_ */:
Module.h
#ifndef HEADERS_MODULE_HAND_H_
#define HEADERS_MODULE_HAND_H_
#include <Gral.h>
int Mod_Init(profile_t *profile);
/* some other functions */
#endif /* HEADERS_MODULE_HAND_H_*/
And when any other structure comes up, I'll declare it in Gral.h and include the header file.
Regarding the compilers, they aren't the same version. The powerpc is quite old now. That would explain the powerpc compilation errors.
Thank you again.
Below is the code of my header file trie.h.
The compiler keep showing the following error:
In file included from speller.c:11:
./trie.h:3:8: error: redefinition of 'letter'
struct letter
^
./trie.h:3:8: note: previous definition is here
struct letter
^
1 error generated.
make: *** [speller.o] Error 1
The code:
struct letter
{
int is_word;
struct letter* arr[27];
};
// fuctions
struct letter* create_trie();
void free_trie(struct letter* trie);
Most likely your file gets included multiple times, hence the redefinition error.
To avoid this problem use include guards:
#ifndef HEADERNAME_DEFINED
#define HEADERNAME_DEFINED
// your code goes here.
#endif // HEADERNAME_DEFINED
or you can use non-standard preprocessor directive like #pragma once to do the job. It results in less code, and sometimes faster compilation speed.
Put that on top of your file:
#pragma once
// your code goes here
Note: The comment (// HEADERNAME_DEFINED part) after #endif isn't necessary. It is just a hint for programmer to know what belongs together.
Before I continue, here is the code which is giving me an error:
#define numScores 3 // the number of test scores which a student will have
struct btreenode{
int studentID; // the ID number of the student at the current node
float scores[3]; // the 3 test scores of the student
float average; // the average of the 3 test scores for the student
struct btreenode *left; // pointer to left side of the tree
struct btreenode *right; // pointer to right side of the tree
};
typedef struct btreenode *Node;
I'm getting the following error when I compile:
btreenode.h:17: error: redefinition of 'struct btreenode'
btreenode.h:28: error: conflicting types for 'Node'
btreenode.h:28: note: previous declaration of 'Node' was here
I have a block comment at the top so the line numbers are off, but
line 17 is the first line "struct btreenode{"
line 28 is the last line "typedef struct btreenode *Node"
Does anyone know why i'm getting these errors?
The header file should not be included more than once. So use macro in header file to avoid multiple inclusion.
#ifndef TEST_H__
#define TEST_H__
/*you header file can have declarations here*/
#endif /* TEST_H__*/
I am assumed that, this kind of approach is not there in your header file.
It looks as though your btreenode.h file is being included (directly or indirectly) multiple times... that's why the "previous declaration" and the "conflicting types" are in the same file at the same line (previous declaration on the first include, conflicting types when it runs into the same line on the next include).
You should use header guards (in btreenode.h) to prevent the header file code from being processed if it's already been included. At the top of the file, add:
#ifndef BTREENODE_H
#define BTREENODE_H
and at the end of the file add:
#endif // BTREENODE_H
That way, whatever is between those will only be compiled if BTREENODE_H was not already #defined from a previous inclusion.
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.
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.