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

为何通过非默认构造函数创建的全局变量会被分配到.bss段?

关于全局对象在.data/.bss段分配的C++疑问

测试代码

test1.cpp(使用非默认构造函数)

// test1.cpp代码
class Derived {
    private:
        int         non_const_int_val=1;

    public:
        Derived(int a) : non_const_int_val(a) {
        }

} dev(0x2f2f2f2f);

int main() {
    Derived derivedObj(0x55555555), derivedObj_copy(dev);

    return 0;
}

test2.cpp(使用默认构造函数)

// test2.cpp代码
class Derived {
    private:
        int         non_const_int_val=1;

    public:

} dev;

int main() {
    Derived derivedObj, derivedObj_copy(dev);

    return 0;
}

现象对比

编译后通过objdump查看全局变量dev的段分配:

  • test2.out中dev位于.data段:
>> objdump -x test2.out | c++filt | grep -E -i "dev"                    
0000000000404028 g     O .data  0000000000000004              dev
  • test1.out中dev位于.bss段:
>> objdump -x test1.out | c++filt | grep -E -i "dev"
000000000040115a l     F .text  0000000000000015              _GLOBAL__sub_I_dev
000000000040402c g     O .bss   0000000000000004              dev

疑问

  1. 如何解释这种特殊行为?
  2. 构造与初始化之间是否存在深层差异?(若我混淆了核心概念请见谅)
  3. 希望提供有用的参考资料。

解答

1. 行为差异的原因

这是C++中静态初始化和动态初始化的区别导致的:

  • test2.cpp中,dev使用默认构造函数,且类成员non_const_int_val的类内初始值是编译期常量(1)。这种情况下,编译器可在编译阶段直接完成dev的初始化,把最终值写入.data段——这属于常量初始化(静态初始化的一种),无需运行时执行构造函数。
  • test1.cpp中,dev调用带参数的构造函数,即便参数是常量,构造函数的执行仍属于动态初始化:编译器无法在编译阶段直接确定对象的内存最终值,会生成全局构造函数(即你看到的_GLOBAL__sub_I_dev),在程序启动(main函数执行前)时调用该构造函数初始化dev。因此dev的内存先被分配到.bss段(初始值为0),运行时构造函数执行后才会被设置为目标值。

2. 构造与初始化的深层差异

在C++中:

  • 初始化是宽泛概念,包含所有为对象设置初始值的操作,比如类内成员初始化、列表初始化、构造函数初始化等。
  • 构造特指通过构造函数创建并初始化对象的过程,是初始化的一种方式。

核心差异体现在执行时机:

  • 静态初始化(含常量初始化)在编译/链接阶段完成,对象初始值直接写入可执行文件的.data(非0值)或.bss(0值)段,运行时无需额外操作。
  • 动态初始化(如调用非默认构造函数、使用非编译期常量初始化)必须在程序运行时(main前的全局构造阶段)执行,对象先分配到.bss段(初始化为0),再由构造函数覆盖为目标值。

3. 参考资料

  • C标准中[basic.start.static]和[basic.start.dynamic]章节:明确了静态初始化、动态初始化的划分规则与执行时机(C11及以后版本)。
  • GCC官方文档中关于全局对象初始化的说明:涵盖GCC对两种初始化的实现逻辑,以及-fno-static-initialization等编译选项的调整作用。

内容的提问来源于stack exchange,提问作者Y.H.Qian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 05:52:49