Search code examples
c++linkerstatic-librariesfriend

Weird error when linking static class with friend function


I am having a lot of troubles with my C++ code but I can't understand why.

I am developing a static library libmylib.a that contains myclass.h and myclass.cpp.

The problem I am having is like this:

// myclass.h
class myClass{
   public:
      myclass();
      myclass(a,b);

     // some methods.

   private:
    int a ;
    int b ;
};

In myclass.cpp I define the constructors methods etc etc and everything works fine: I am able to use the library in my main.cpp code.

I then added a friend function:

// myclass.h
class myClass{
   public:
      myclass();
      myclass(a,b);
      friend void foo() ;

     // some methods.

   private:
    int a ;
    int b ;
};

I define the foo function in myclass.cpp like this

// myclass.cpp
void foo(){
  cout << "In foo function " ;
}

The problem is that if I try to use foo() in main.cpp I get a compile error that states:

//main.cpp
#include "myclass.h" // foo() is declared here!

foo() ;

main.cpp:62:6: error: ‘foo’ was not declared in this scope

Now I really can't understand where the problem is. I notice that after adding the friend function it seems that the linker doesn't use mylib anymore, but I can't understand why. Moreover it is strange, because if I comment foo() in main.cpp myclass and its methods can be used without problems.

What am I doing wrong? I spent two hours trying to figure out, but really can't understand!!!

Solution: following the advice in the answer:

// myclass.h
void foo() ; // the function has to be declared outside the class

class myClass{
   public:
      myclass();
      myclass(a,b);
      friend void foo() ; // but here you have to specify that 
                          // is a friend of the class!
     // some methods.

   private:
    int a ;
    int b ;
};

Solution

  • This is not a linker error, it is a compiler error. The compiler is telling you that it does not know how to call function foo, because it lacks its definition or declaration.

    Declaring a function as a friend is no substitute for a proper declaration. When you say foo is a friend, you do not also introduce foo into a scope. In a sense, friendship declaration is a private detail of your class invisible from the outside.

    In order to use a function in C++ you need to declare it first. This is usually done through a header file corresponding to the implementation file, but you can do it simply like this:

    void foo();

    If foo is defined in the same file as main, you can move foo ahead of the main to fix the problem (seeing a function definition prior to first use is OK with the compiler).