通过非默认构造函数构造一个全局变量,为什么可以分配到.bss段?

问题描述 投票:0回答:1

我写了两段cpp源代码,唯一的区别是一个文件指定了非默认构造函数,而另一个则没有:

// code for `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;
}
// code for `test2.cpp`
class Derived {
    private:
        int         non_const_int_val=1;

    public:

} dev;

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

    return 0;
}

test2.cpp
中,全局变量
dev
将被分配到
.data
部分,因为它是构造并初始化的,我们可以通过检查elf来验证它:

>> objdump -x test2.out | c++filt | grep -E -i "dev"                    
0000000000404028 g     O .data  0000000000000004              dev

令我惊讶的是,它并不适用于

test1.cpp
,而且我无法弄清楚(我认为它也应该是初始化。):它位于
.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

我将

g++
gcc 10.2.0
版本一起使用。

  • 那么我们如何解释这种有线行为呢?
  • 或者构造初始化之间是否存在一些深刻的区别(如果我弄错了一些核心概念,请原谅我。)?
  • 有用的参考文献也是首选。

谢谢。

我抛弃了这个小精灵,并指出了令我困惑的行为。

c++ constructor elf
1个回答
0
投票

在第二个片段中,

dev
常量初始化。它是通过调用构造函数来初始化的。默认构造函数是 constexpr,使其成为常量表达式。
在您的第一个代码片段中,由于您的构造函数不是 

constexpr

,因此它是动态初始化的。它是零初始化的,然后在程序启动时运行实际的初始化程序(在

._GLOBAL__sub_I_dev
内)。
如果您在启用某些优化的情况下进行编译,编译器应该能够看到 

dev(0x2f2f2f2f)

本质上是一个常量,并且允许将其

优化
为常量。

© www.soinside.com 2019 - 2024. All rights reserved.