This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Global Variables in Header File

I want to put a global variable in the header file by declare it as an "extern" variable.  Since it is a variable, many source files are using it, so I include the .h (header file) in each source file where the global being used.  However, the CCS3.3 does not like it, and it gave me error that the variable being redefined in two source files.

What would be a refence to declare a global variable in a header file using CCS3.3?

  • You would declare the variable in the header file to include in multiple files like this

    extern int x;

    and you would declare it in one and only one object (.c) file like this

    int x;

    In this way, the header file declaration declares the variable but tells the compiler not to allocate memory for it because the actual variable will be located at link time.  The declaration for the one object file tells the compiler to allocate memory for the variable in this object and all references to it will get resolved at link time.  If you happen to declare the second form multiple times, then the linker will not know which particular variable to link all the other references to and thus you will get an error.  Many people make this mistake by putting both declaration forms in the header file but this in effect declares the variable and allocates memory for it every time the header file is included (this can include multiple declarations in the same source file if the header file gets included several times via different header paths).

    Jim Noxon

     

  • Thanks for your help.  However, I still found several errors as symbols being redefined in multiple object files like these

    error: symbol "_T_roff" redefined: first defined in
       "C:\\Projects\\BACNet\\BACNet\\Debug\\BACNet.obj"; redefined in
       "C:\\Projects\\BACNet\\BACNet\\Debug\\DSP2833x_CpuTimers.obj"
    error: symbol "_N_max_master" redefined: first defined in
       "C:\\Projects\\BACNet\\BACNet\\Debug\\BACNet.obj"; redefined in
       "C:\\Projects\\BACNet\\BACNet\\Debug\\DSP2833x_CpuTimers.obj"
    error: symbol "_T_turn_around" redefined: first defined in
       "C:\\Projects\\BACNet\\BACNet\\Debug\\BACNet.obj"; redefined in
       "C:\\Projects\\BACNet\\BACNet\\Debug\\DSP2833x_CpuTimers.obj"
    error: symbol "_N_poll" redefined: first defined in
       "C:\\Projects\\BACNet\\BACNet\\Debug\\BACNet.obj"; redefined in
       "C:\\Projects\\BACNet\\BACNet\\Debug\\DSP2833x_CpuTimers.obj"

    Let me clarify by using simple example.

    - I have a headfile.h file that includes extern global variables x, y, z, and many void functions such as void aaa(void) and void bbb(void). 

        #ifndef BNETFUNCTIONS_H
        #define BNETFUNCTIONS_H

        extern int x, y, z;

        void aaa (void);

        void bbb (void);

        #endif

    - I also have AAA.c file that define aaa(void) function and a BBB.c file defining a bbb(void) function.

    - The AAA.c file uses a global variable x, so AAA.c file will have

        #include "headfile.h"

        int x;

        void aaa (void) ( ... }

    - The BBB.c file uses all global variables x, y, z, so BBB.c file has

        #include "headerfile.h"

        int y, z;

        void bbb (void){ ... }

    If I remove the #iclude header.h file in the c file then I got either function not defined or variable not define.  Please help me to clarify the usage of header file and the global variables in the sub c files in CCS3.3.  Many thanks.

  • So your code example looks valid but the errors you show indicate all is not copacetic.  The errors won't show up unless the variable has been defined multiple times.  Is it possible you are using a global variable name that a library file is also using?  Is it possible you have #included a .c file by accident when you meant a .h file?  This is a linker issue so I suspect if you search through your files of the BACNet.c and DSP2833x_CpuTimers.c files for the offending identifiers, you may find where they are defined in both source files.

    Do you have whole program optimization turned on?  I seem to remember that could cause some problems with global variables as the compiler effectively flattens the entire code set int a single translation unit.  I thought this issue had been fixed though.

    If none of these suggestions helps, can you package up your code for me to take a look at?

    Jim Noxon

     

  • I verified the code, and .h is the only include file that I added into the other file.  I did not turn on the optimization yet b/c I'm still in the debug mode.  Please send me your email, so I can pack my code to send it to you.  Thank you very much for your help.

  • Please send your code to vo@jimineering.com

    Jim Noxon

     

  • Thanks for your help.  I figured out the errors, so please do not take time to debug my file.

  • Can you enlighten us?  It is always better for the community on whole to see the solution to problems.

    Glad to hear things are working now.

    Jim Noxon

     

  • I used extern for variables that are used globally.

  • Minhtuan Vo said:

    I used extern for variables that are used globally.

    "To reference a global variable, some compilers require that the declaration within the function include the keyword extern before the type designation to tell the computer to look outside the function for the variable."

    I am using CCS 4.2.3.00004 on F2808 processor. We have a structure that is used on multiple files. Unique structure - it is an array of 8 that has about 10 members, with a mix of Uint16 and int16 types.

    Inside of a specific function that is using that structure, I have specified

    extern

     

    However, when I try to access a member of the structure in code, I get an error:

    struct V3Stack StackArray; // V3Stack is the typedef associated with the structure.

  • Clarification:

    Inside of a specific function that is using that structure, I have specified

    extern struct V3Stack StackArray; // V3Stack is the typedef associated with the structure.

     

    Some code that accesses this structure is as follows

     

    if

    ((StackArray[i].Stack_Mode) == MODE1)

    {

    }

    However, when I try to access a member of the structure in code, I get an error:

    error: incomplete type is not allowed

  • The short answer is you need to remove the struct keyword from your extern declaration.  Probably need to do the same where the array is actually declared.

    The long answer is...

    From the code

    Todd Anderson78572 said:

    extern struct V3Stack StackArray; // V3Stack is the typedef associated with the structure.

    I am assuming you have some where a typedef of the following form

    typedef struct
    {
      /* ... */
      int a;
      int Stack_Mode;
      /* ... */
    } V3Stack;

    Of course this is assuming the type of Stack_Mode but you get the idea.  In this case, the identifier V3Stack is an ordinary identifier which represents a type.  Note that it includes the fact it is representing a struct type.

    In your code where you declared

    extern struct V3Stack StackArray;

    The V3Stack is now a tag name.  Since tag names and ordinary identifiers exist in seperate name spaces, there is no conflict.  This is what allows you to do this

    struct my_struct
    {
      /* ... */
    } my_struct;

    and not have any compiler errors.

    In effect, your extern declaration is called a forward declaration.  In this case, the StackArray delcared in the extern statement refers to a structure represented by the tag name V3Stack (which is also introduced at this point) but since there is no definition associated with the tag V3Stack, there is no knowledge of the structure associated with it.  You are also experiencing identifier masking where names declared within inner scopes can mask names declared in outer scopes thus the question in your if statement is trying to access the incomplete type StackArray associated with the struct tag V3Stack rather than the array declared somewhere else.

    Jim Noxon

  • Jim:

    Yes, that is what the solution turned out to be...

    Thanks,

    Todd Anderson