You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何C++代码的隐式生成成员函数未出现在符号表中?

为什么C++中隐式生成或默认的成员函数不在符号表中?

先看你的示例代码:

#include <iostream>

class Foo
{
public:
        Foo (int N) : values {new int[N]}{
                for (int i = 0; i < N; i++) {
                        values[i]=2*i;
                }
        };

private:
        int *values;
};

int main()
{
        Foo A {20};
        Foo B {A};
        Foo C {std::move(A)};

        return 0;
}

编译后执行nm -C a.out | grep Foo,输出只有:

00000000000011b8 W Foo::Foo(int)
00000000000011b8 W Foo::Foo(int)
000000000000122a W std::remove_reference<Foo&>::type&& std::move<Foo&>(Foo&)

哪怕给类加上Foo(const Foo&)=default;,nm输出还是没变化;但手动定义拷贝构造Foo(const Foo&){};后,就能看到对应的符号:

00000000000011ce W Foo::Foo(int)
0000000000001240 W Foo::Foo(Foo const&)
00000000000011ce W Foo::Foo(int)
0000000000001240 W Foo::Foo(Foo const&)
000000000000124f W std::remove_reference<Foo&>::type&& std::move<Foo&>(Foo&)

核心原因在于编译器的优化规则和特殊成员函数的生成逻辑:

  • 按需生成+内联优化:C++标准规定,隐式生成的特殊成员函数(拷贝构造、移动构造、析构等)只有在被ODR-used(即需要具体定义的场景)时才会生成。但就算生成了,编译器会默认对这些简单的默认实现做内联优化——直接把函数逻辑嵌入调用处,不会生成独立的函数符号,自然在nm里看不到。
  • =default和隐式生成等价:用=default声明的函数,本质还是编译器生成的默认实现,和隐式生成的规则完全一致,依然会被内联优化,不会留下独立符号。
  • 手动定义函数不会自动内联:当你手动编写函数体(哪怕是空实现),编译器不会自动内联该函数(除非显式加inline关键字),因此会生成独立的函数符号,nm就能捕获到。

如果要验证这个结论,可以关闭内联优化后编译:

g++ -fno-inline your_code.cpp

再执行nm -C a.out | grep Foo,就能看到隐式生成或=default声明的拷贝构造、移动构造的符号了。

内容的提问来源于stack exchange,提问作者TCD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 05:43:14