6

I have a data type and I can instantiate a variable of that type. like this:

FetchAddr faddr(VirtualMemoryAddress( 0x0a ));

The definition of FetchAdr is:

struct FetchAddr {
   VirtualMemoryAddress theAddress;
   FetchAddr(VirtualMemoryAddress anAddress)
     : theAddress(anAddress)
   { } 
};

Now I have a class that faddr is a private (or public) variable

class FLEXUS_COMPONENT(BPred)  {
   static FetchAddr faddr;
   public:
     FLEXUS_COMPONENT_CONSTRUCTOR(BPred)
        : base( FLEXUS_PASS_CONSTRUCTOR_ARGS )
     {
        faddr = VirtualMemoryAddress( 0x0a );
     }
   ...
}

Assume the macros are defined properly.

The code compiles and links without any problem. However when I start the program, it says:

 "undefined symbol: _ZN6nBPred14BPredComponent8faddr"

it says there no symbol for faddr.

any idea about that?

mahmood
  • 23,197
  • 49
  • 147
  • 242

3 Answers3

4

When you declare a static member you also have to define it somewhere, like in a .cpp file. And also remember to link to this file.


Problem number 2 - FetchAddr doesn't have a default constructor.

If you need to have faddr as a static member of the class, you also need to give it a value when it is defined, like:

FetchAddr FLEXUS_COMPONENT(BPred)::faddr(VirtualMemoryAddress( 0x0a ));

That creates an faddr that is shared by all FLEXUS_COMPONENT(BPred) objects.

If you rather have it that each object has its own copy of the faddr variable, you can make it non-static and initialize it in the constructor:

class FLEXUS_COMPONENT(BPred)  {
   FetchAddr faddr;
   public:
     FLEXUS_COMPONENT_CONSTRUCTOR(BPred)
        : base( FLEXUS_PASS_CONSTRUCTOR_ARGS ),
          faddr(VirtualMemoryAddress( 0x0a ))
     { }
   // ...
};
Bo Persson
  • 90,663
  • 31
  • 146
  • 203
  • Is there any way to avoid static variable? I tried to remove "statis" key word but I get compilation error: BPredImpl.cpp:36: error: no matching function for call to ‘FetchAddr::FetchAddr()’ – mahmood Jul 31 '11 at 12:47
  • ok thanks I tried the "non static" approach and it works well. – mahmood Jul 31 '11 at 13:23
3

You must define the static variable elsewhere.

FetchAddr FLEXUS_COMPONENT(BPred) :: faddr;

In a single TU.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • error: expected initializer before ‘:’ token also what does TU mean? – mahmood Jul 31 '11 at 12:44
  • TU = Translation Unit. A translation unit is a `.cpp` file after the preprocessor has been run (and so, after all `#include`'d files have been expanded). It's basically a source file plus all the headers it includes. – jalf Jul 31 '11 at 12:59
  • 1
    @mahmood: Your error is because the macro doesn't just name the class, it also inherits it from some base classes, which cannot appear in this sense. You must use the class's real name instead of the macro call- and this use of macros is hideous, by the way. – Puppy Jul 31 '11 at 13:03
2

Try compiling with the -Wl,--no-undefined so that the linker will refuse to complete the link if there is even a single symbol which is not defined in a library or any other dependencies.

faddr has not been properly linked and without seeing more of your program, it is hard to tell what else is going on.