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

Error in calling a static function in a namespace

本文关键字:出错 静态函数 调用 命名空间      更新时间:2023-10-16

我得到以下错误:

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

有人能解释一下原因吗?

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

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

  • x.h中的foo声明中删除static说明符,这可能没有理由
  • x.h中定义foo。请注意,这种方法会增加程序的大小,因为每个翻译单元都会生成函数的私有副本。函数不应定义为在标头中具有内部链接,也就是说,当它们打算在所有程序中使用时
  • main.cpp中定义foo。当然不是你想要的

正确的解决方案当然是第一个。对其他人进行了解释以说明原因。

有关详细信息,请阅读本页。此外,请注意声明定义之间的差异,这不在本问题的范围内。

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

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