1

I am using Keil MDK ARM to develop a project. However, when I am trying to build my code, the software tool throws the ERROR: L6218E : Undefined symbol Bit (referred from main.o). Where Bit is a struct that I am using to store boolean values. For eg:

In variable.h file

struct
{
    unsigned bPowerONStatus : 1;
    unsigned bTimerONStatus : 1;
} extern Bit;

In main.c file:

#include variable.h

int main()
{
    while(1)
    {
        ReadTimerStatus();
        if(Bit.bPowerONStatus)
        {
            // System is ON
        }
        else
        {
            // System if OFF
        }
    }
}

In PowerChecker.c file

#include variable.h

void ReadTimerStatus(void)
{
    if(Bit.bTimerONStatus)
    {
        Bit.bPowerONStatus = 1;
    }
    else
    {
        Bit.bPowerONStatus = 0;
    }
}

What am I doing wrong here? What is the correct method of defining a struct, that will be used in multiple source files?

R.Tinker
  • 13
  • 5
  • 2
    Does this answer your question? [How do I use extern to share variables between source files?](https://stackoverflow.com/questions/1433204/how-do-i-use-extern-to-share-variables-between-source-files) – Lanting Dec 09 '19 at 08:48
  • 4
    For one, you should use quotes for the include statement -- `#include "variable.h"` (assuming it's in the same folder as main.c and PowerChecker.c). – gstukelj Dec 09 '19 at 08:51
  • 2
    I'm not sure what `struct {... } extern Bit` is supposed to do. What you _should_ probably do is to create a typedef struct in the header, then create an instance of that struct elsewhere. Also note that using bit-fields aren't recommended practice, since they are wildly compiler-specific. – Lundin Dec 09 '19 at 09:31

1 Answers1

1

Declaring a variable at file scope with the keyword extern, but with no initializer declares the variable to have external linkage, but does not define the variable. There needs to be a definition of the variable elsewhere in your program.

In the case of your Bit variable, it has been declared with an anonymous struct type that has no type alias, so there is no way to use the same type when defining the variable. In order to fix that you need to either define the struct type with a tag, or define the struct type within a typedef declaration, or you can do both.

It is more conventional to put the storage class specifier such as extern at the front of the declaration.

In variable.h:

struct StatusBits
{
    unsigned bPowerONStatus : 1;
    unsigned bTimerONStatus : 1;
};

extern struct StatusBits Bits;

In only one C file, e.g. main.c or variable.c:

#include "variable.h"

struct StatusBits Bits;

Note that the struct StatusBits Bits; above has external linkage and has no initializer, but has not been declared extern, so it is a tentative definition of the Bits variable. Unless overridden by a definition of the same variable with an initializer, it will behave as if it has been initialized with {0}.

Ian Abbott
  • 15,083
  • 19
  • 33