views:

260

answers:

2

I have the following in header file.

namespace silc{
   class pattern_token_map
   {
      /* Contents */
   };

   pattern_token_map* load_from_file(const char*);
}

In the CPP file (this has got proper includes)

pattern_token_map* load_from_file(const char* filename)
{
   // Implementation goes here
}

In another CPP file. This has got all proper includes.

void some_method()
{
    const char* filename = "sample.xml";
    pattern_token_map* map = load_from_file( filename ); // Linker complains about this.
}

I am getting a linker error saying that undefined reference to load_from_file. I am not able to see what is going wrong here.

Any help would be appreciated.

Compiler : G++ OS : Ubuntu 9.10

Edit

Here is the linker command used.

g++ -L/home/nkn/silc-project/third_party/UnitTest++ -o tests.out  src/phonetic_kit/pattern_token_map.o  tests/pattern_token_map_tests.o  tests/main.o -lUnitTest++

Error is from pattern_token_map_tests.o and the function is available in pattern_token_map.o. So I guess the order of linking is not making the problem. (I have removed some files from the command to simplify it)

A: 

In your link phase, are you linking in the object file created by compiling the first cpp file? Linker errors like these occur when one object references a symbol that is not included in the objects being linked.

Edit: I'm still reasonably confident that this is the problem. In the first file, is there a preprocessor symbol redefining load_from_file?

Adam Wright
Yes. I am linking all the object files. Added the linker command. Please have a look.
Appu
+6  A: 

When you implement it, you have to make sure you implement the right function:

namespace silc {
pattern_token_map* load_from_file(const char* filename) {
   // Implementation goes here
}
}

If you instead did this:

using namespace silc; // to get pattern_token_map
pattern_token_map* load_from_file(const char* filename) {
   // Implementation goes here
}

Then you'd be defining a new function rather than silc::load_from_file.

Avoid using directives ("using namespace ...;") outside of function scope, as a general guideline:

using namespace silc; // outside function scope: avoid

silc::pattern_token_map*                      // qualify return type
random_function(silc::pattern_token_map* p) { // and parameters
  using namespace silc; // inside function scope: fine
  pattern_token_map* p2 = 0; // don't have to qualify inside the function
                             // if you want to use the using directive
  silc::pattern_token_map* p3 = 0; // but you can always do this
  return 0;
}
Roger Pate
Thanks. By saying "Avoid using directives ("using namespace ...;") outside of functions.", do you mean that avoid writing it on top of cpp files. Write it inside each functions instead. Is that what you meant?
Appu
Yes, if you want to use it inside a function, that's fine. You rarely need it anyway, as you can use the form in my first piece of code to implement your functions in cpp files.
Roger Pate
I hadn't thought of restricting `using` directives to inside function bodies. +1
Peter Kovacs
While this advice is considered good coding practice by most, be advised that it's incredibly annoying to follow.
Andreas Bonini