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

Dee*_*pak 5 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
Run Code Online (Sandbox Code Playgroud)

在构建以下代码时:

main.cpp中

#include "x.h"

int main()
{
    X::foo();
}
Run Code Online (Sandbox Code Playgroud)

XH

namespace X
{
    static int foo();
}
Run Code Online (Sandbox Code Playgroud)

x.cpp

#include "x.h"

namespace X
{
    int foo()
    {
        return 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

谁能解释一下原因?

Kal*_*ish 7

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

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

  • staticxh中foo的声明中删除说明,因为没有理由在那里.
  • xh中定义foo.请注意,此方法将增加程序的大小,因为将为每个翻译单元创建该函数的私有副本.函数应该永远定义在头内部联动,即当他们打算在所有的程序中使用.
  • main.cpp中定义foo.肯定不是你的意图.

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

有关更多信息,请阅读此页面.另外,请注意声明定义之间的区别,这超出了本问题的范围.


Vla*_*cow 5

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

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