12

I am getting the following error:

x.h:3:13: warning: ‘int X::foo()’ used but never defined
/tmp/ccK9qSnq.o: In function `main': main.cpp:(.text+0x7): undefined reference to `X::foo()'
collect2: error: ld returned 1 exit status

while building the following code:

main.cpp

#include "x.h"

int main()
{
    X::foo();
}

x.h

namespace X
{
    static int foo();
}

x.cpp

#include "x.h"

namespace X
{
    int foo()
    {
        return 1;
    }
}

Can anybody explain the reason?

djsp
  • 2,174
  • 2
  • 19
  • 40
Deepak
  • 1,038
  • 5
  • 17
  • 44
  • 8
    It's static. Perhaps you meant to make it `extern` (which functions are by default)? `static` for global functions/variables means "no other source files can see/use this function/variable". [I once wrote a mediocre blog post on what `static` means](http://www.mjbshaw.com/2012/11/the-static-modifier.html). – Cornstalks Sep 12 '14 at 16:57
  • `static` has many meanings, depending on context, and I don't think you want it here. – crashmstr Sep 12 '14 at 16:57

2 Answers2

14

The linkage of a function declared static is internal, which means that it may only be referred to from the current translation unit. Even if several translation units see the same declaration, a private version of the function is expected for each one.

What happens in your case is that the function foo that is defined in x.cpp is not available to other translation units. When the compiler translates main.cpp, it annotates the symbol as "missing" but does not complain. Later, at the linking stage, the linker cannot find the private function foo that is referred to in the object main. To solve this, you could:

  • Remove the static specifier from foo's declaration in x.h, for which there isn't presumably a reason to be there.
  • Define foo in x.h. Note that this approach will increment the size of your program, because a private copy of the function will be made for every translation unit. Functions should never be defined with internal linkage in headers, that is, when they are intended to be used across all the program.
  • Define foo in main.cpp. Surely not what you intended.

The right solution is, of course, the first. The others were explained to show why.

For more information, read this page. Also, note the difference between a declaration and a definition, which is outside the scope of this question.

djsp
  • 2,174
  • 2
  • 19
  • 40
5

You have to define the static function either in the header (in this case removing its definition in X.cpp) or additionally in main.cpp. Otherwise main.cpp will not see its definition. In X.cpp there is defined another static function foo with the same name. There is no external linkage for static functions. They have internal linkage and shall be defined in compilation units where they are used.

So X.cpp has its own static function foo which it defined. But main.cpp did not define its own static function with name foo. it only declared it due to inclusion of the header.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • See also: http://stackoverflow.com/questions/11623451/static-vs-non-static-variables-in-namespace –  Sep 12 '14 at 17:06