在命名空间中调用静态函数时出错

时间:2014-09-12 16:54:51

标签: c++ linkage

我收到以下错误:

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

在构建以下代码时:

的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;
    }
}

有人可以解释原因吗?

2 个答案:

答案 0 :(得分:6)

声明为static的函数的链接是内部的,这意味着它只能从当前的转换单元引用。即使多个翻译单元看到相同的声明,也希望每个翻译单元的私有版本。

在您的情况下会发生的情况是 x.cpp 中定义的函数 foo 不可用于其他翻译单元。当编译器翻译 main.cpp 时,它会将符号注释为"缺少"但不抱怨。稍后,在链接阶段,链接器无法找到对象 main 中引用的私有函数 foo 。要解决这个问题,您可以:

  • xh 中的static声明中删除foo说明符,其中不大概是理由是在那里。
  • x.h 中定义 foo 。请注意,此方法将增加程序的大小,因为将为每个翻译单元创建该函数的私有副本。函数应该从不 定义并在标题中使用内部链接,也就是说,当它们打算在所有程序中使用时。
  • main.cpp 中定义 foo 。肯定不是你想要的。

正确的解决方案当然是第一个。其他人被解释说明原因。

有关详细信息,请阅读this page。另外,请注意声明定义之间的区别,这超出了本问题的范围。

答案 1 :(得分:3)

您必须在标题中定义静态函数(在本例中,在X.cpp中删除其定义)或者另外在main.cpp中定义静态函数。否则main.cpp将无法看到它的定义。在X.cpp中,定义了另一个具有相同名称的静态函数foo。静态函数没有外部链接。它们具有内部联系,应在使用它们的编译单元中定义。

所以X.cpp有自己定义的静态函数foo。 但是main.cpp没有使用名称foo定义自己的静态函数。它只是由于包含标题而声明它。