Multiple definition of variable.

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Hi everyone,

   

I am using a PSOC5LP, CY8C5888LTI-LP for a project in which a RC boat is controlled w/ GPS and IMU.

   

To clean up my code I created 5 header files associated w/ 5 code files : 

   

Global, Autopilot, ToMatlab, IMU and GPS.

   

Before I decided to clean up, everything was compiling without error. 

   

And Now Psoc creator (V3.3) is throwing me 12 errors (all located in Global.c). The weird thing is when I click on the errors, it send me to some lines on the code where the variable is not even present.

   

I tried to clean up but when I build again, Psoc creator throw me the same errors.

   

I would really appreciate your help. I put a workspace bundle in the attachment. Thanks.

0 Likes
1 Solution
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

There are a few rules to follow when building C modules which consist of corresponding .c and .h files.

   

Despite the required #ifndef ... mimic:

   

Do not define any variables or functions in a .h file, declarations only. So no ram/flash gets allocated with a .h file.

   

Always #include the .h file in the corresponding .c

   

Variables that need to be accessed from outside the module should be defined in the .h as extern and are declared in the .c

   

Global variables and functions in the .c file that are not accessed from outside should be declared as "static".

   

Advantages are quite obvious: You can pick a module and re-use the original code in a different project without modifications, so no need for a cut & paste which makes updating/correcting difficult (In which projects did I use that module???)

   

 

   

To make things more clear:

   

uint8 Myfunc(void);    //  This is a definition, a function prototype

   

double f;   //  This is a declaration. Allocates memory for f

   

extern int Counter;    //  This is a definition. Just tells the compiler that there is a variable anywhere

   

float Square(float x)    //  This is a declaration. The fuction will occupy some flash
    return x * x;
}

   

 

   

Happy coding.

   

Bob

View solution in original post

0 Likes
10 Replies
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

Did you do a clean build?

   

One thing that one should do with all header files to to wrap their content in an IFNDEF block like:

   

#IFNDEF __NAME_H__

   

#DEFINE __NAME_H__

   

content...

   

#ENDIF

   

to ensure that the code is only included once.

   

Then you can include the header files that you really need directly in the C files that need them (e.g. global.c should include project.h, global.h, gps.h and so on.

0 Likes
Anonymous
Not applicable

Thank you very much for your tip. I'll do it right now.

   

And yes, I did  a "clean project" before trying  to compile it again. Is this what you are referring to ?

0 Likes

Yes, either do a separate 'clean project' before 'build' or just 'clean and build'.

0 Likes
Anonymous
Not applicable

Thank for your answer but it didn't work. I got the same errors, even after I did a clean project and a build. But my code is more clean with the wrapper though.

   

Edit : I tried to use "external" on some variables but it didn't work.

   

It put all the code back in 1 file (the main) and it was working perfectly. I guess I'll stick to that.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

There are a few rules to follow when building C modules which consist of corresponding .c and .h files.

   

Despite the required #ifndef ... mimic:

   

Do not define any variables or functions in a .h file, declarations only. So no ram/flash gets allocated with a .h file.

   

Always #include the .h file in the corresponding .c

   

Variables that need to be accessed from outside the module should be defined in the .h as extern and are declared in the .c

   

Global variables and functions in the .c file that are not accessed from outside should be declared as "static".

   

Advantages are quite obvious: You can pick a module and re-use the original code in a different project without modifications, so no need for a cut & paste which makes updating/correcting difficult (In which projects did I use that module???)

   

 

   

To make things more clear:

   

uint8 Myfunc(void);    //  This is a definition, a function prototype

   

double f;   //  This is a declaration. Allocates memory for f

   

extern int Counter;    //  This is a definition. Just tells the compiler that there is a variable anywhere

   

float Square(float x)    //  This is a declaration. The fuction will occupy some flash
    return x * x;
}

   

 

   

Happy coding.

   

Bob

0 Likes
Anonymous
Not applicable

Thank you very much for your reply Bob. I will apply your rules. I managed to create some header files with only struct definition and the define (no variables or function definition). I made less header files though. Will it be interesting if I put a bundle of my new version  in attachment ?

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Will it be interesting if I put a bundle of my new version  in attachment ? Yes, of course. I'll have a look into. But be warned: I usually focus on readability and safety of program code.

   

 

   

Bob

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Ok here is my bundle.

   

I just want to warn you that I put my global variables in a header file GVL.h temporary so my main code could be a little less messy.

   

I do got errors on the file but once compiled, everything works ok. Once the project will reach the end I will put the  global variables back in the main.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

As you can see by yourself: your project is rather difficult to read due to poor modularisation. When searching for a function or functionality it is not easy to get to the correct point. As I said, make definitions for modules (matlab is a good example) and create a .h and a .c file offering only the required functions.

   

        if (strcmp(&Direction,"S"))//Starboard
This is an error!!! Direction is declared as a character, correct to

   

        if (Direction =='S'))//Starboard

   

There are some more of those, check that.

   

            L3GD20_ReadGyro(&gyroData);
is flagged with a warning!

   

gyroData is a Vector3 *, so you are trying to take the address of a pointer. Not good... use

   

            L3GD20_ReadGyro(gyroData);

   

As a tip: divide et impera! Take small steps to modularisation, not all at once.

   

Variables accessed in main() only do not have to be defined as global. Define them as static in main(), that will preserve stack and helps modularisation. Example:   
TimerPeriod = Timer_MATLAB_ReadPeriod();

   

Take care with a late (too late) CYGlobalIntEnable. there are some components that require interrupt enabled at initialization.

   

I always suggest to create a InitializeSystem() function. This shortens main().

   

All settings and #defines that are project specific go into a separate .h file. Imagine, you use that very same project with a different boat with different motors and different IMU devices, what (and where) do you have to apply changes?

   

1 big file (as it is now)
several smaller files (where you can easily get to)
one small file (which would be best)

   

When you are building a work that should be judged by somebody else, how will he (or she) do that? Runs -doesn't run basis? Or will there be a closer look at (into) the sources? What will be the first thing to look at? The answer is: main() so try to make it easy to find, easy to read and very easy to understand!! Take out small functions to describe what you want to do as:

   

                    GPS.DGPS_mess_available = 0;
                    GPS.DGPS_Corr_Long  = 0;
                    GPS.DGPS_Corr_Lat   = 0;
                    GPS.DGPS_Corr_Alt   = 0;
This could be shortened to
                   ZeroGPS();

   

 

   

Well, enough of hints and advices, happy coding!

   

Bob

0 Likes
Anonymous
Not applicable

Thank you very much for your detailed  answer and your time. I will correct the errors as soon as I can. If you are around Auckland one day I'll buy you a drink 😉 !  Code, here I come !

0 Likes