【问题标题】:Why does the size of my binary depend on the size of my array?为什么我的二进制文件的大小取决于我的数组的大小?
【发布时间】:2015-07-25 01:15:38
【问题描述】:

我最近偶然发现了一个非常奇怪的代码膨胀效应,我真的无法向自己解释......以下是一个最小的工作示例:

#include <array>

const int SIZE = 4000000;

struct Foo
{
    static Foo& GetInstance()
    {
        static Foo instance;
        return instance;
    }

    std::array<float, SIZE> Bar;
};

int main()
{
    Foo::GetInstance().Bar[0] = 1.0f;
    return 0;
}

生成的二进制文件(使用 GCC MinGW 4.9.2 x86_64 posix sjlj 构建)大小为 15.28 MB。但是,如果您设置例如SIZE = 1 你会得到一个 17 KB 二进制文件。

那么为什么二进制的大小取决于这里数组的大小呢?显然,该效果是由结构是单例引起的。然而,我仍然看不出编译器会膨胀二进制文件的任何合理推理。感谢您的帮助!

(经过优化和不经过优化以及仅使用 -std=c++11 标志的测试。顺便说一句,这也发生在 C 样式数组中......)

【问题讨论】:

  • 因为具有静态存储持续时间的对象通常存储在可执行文件的特殊部分(当然,这取决于实现)。因此,您的对象越大,该部分就越大。
  • 是的,单身人士。静态变量值存储在程序文件中,显然 GCC 并不关心大多数值是 0。除此之外,4Mio 静态数组看起来是错误的。这么大的堆栈数组甚至是不可能的(通常的系统+设置),所以不要在没有动态的东西的情况下制作这样的数组。
  • @DarkFalcon:但是零初始化的对象通常不会存储在可执行文件中,因为这非常浪费;在.bss 部分中为它们提供了一个条目,因此它们可以在运行时进行初始化。据推测,这个特定的编译器出于某种原因不会对局部静态变量执行此操作。
  • FWIW,代码给了我一个 8kb 在 Linux 上的可执行文件。这一定是MinGW的一个怪癖。我建议你停止尝试使用 Windows,这没有任何好处。
  • @MikeSeymour 这与(您对窗口的主观意见)无关!使用 MSVC13,我有一个 10kb 的可执行文件,使用本机工具链。

标签: c++ arrays c++11 mingw stdarray


【解决方案1】:

“显然,这种影响是由于结构是单例造成的。但我仍然没有看到编译器会膨胀二进制文件的任何合理推理。”

是的,您的观察是正确的。您的单例实例具有静态存储持续时间。数组的大小决定了您的二进制代码大小,这是因为您的单例对象的所有初始化都是在编译时完成的,并且可能会转到 .text 部分。

但这一切都取决于当前使用的编译器实现和优化级别。

【讨论】:

    猜你喜欢
    • 2019-07-26
    • 1970-01-01
    • 2019-02-16
    • 2022-11-28
    • 2012-04-13
    • 1970-01-01
    • 2022-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多