【问题标题】:Does code in header file increases binary size?头文件中的代码会增加二进制大小吗?
【发布时间】:2010-12-07 06:33:45
【问题描述】:

考虑一下:

class Foo{
      void func1(){
            /*func1 code*/

      }

      void func2(){
            /*func2 code*/

      }


};

案例 1:Foo.h 中的类 Foo

案例 2:Foo 类在 Foo.h 和 Foo.cpp 之间很好地分离

其他各种 cpp 文件包括 Foo.h

我的问题是...案例 1 会导致更大的二进制文件吗?

【问题讨论】:

    标签: c++ binary executable


    【解决方案1】:

    如果您在标头中有代码定义,编译器可能会在您包含 .h 时为每个函数创建冗余副本。这些冗余副本也可能会触发链接器的错误,因此除了内联函数外,这种做法通常不受欢迎。

    【讨论】:

    • 我实际上没有得到链接器错误。只关心代码大小。感谢回复
    • 当然,如果这是 C 代码,那么会有链接器错误。
    • @hotadvice:C 没有链接器错误;编译器会在调用链接器之前将代码视为无效而拒绝。
    【解决方案2】:

    如果编译器决定不内联这些函数,并为它们生成单独的主体,这些主体将出现在每个使用它们的目标文件中,但带有链接器的特殊标志 - '弱符号'。当链接器找到这个标志时,它会将具有该名称的所有符号组合成一个结果符号(如果这些符号的主体或大小不同,它可能会产生错误消息)

    RTTI info 和 vtables 也使用相同的场景。

    对于动态库,如果它们使用相同的类,弱符号连接可能会在运行时发生。

    【讨论】:

      【解决方案3】:

      如果头文件中的函数声明为static,那么包含该头文件的每个模块(源文件)都会在目标文件和最终可执行文件中存储该函数的副本尺寸会更大...

      【讨论】:

      • 示例标题没有说明静态函数。
      【解决方案4】:

      也许会,也许不会。它实际上与头文件无关。这里重要的是您的成员函数是在类定义中定义的。当成员函数被这样定义时,它们被视为内联函数。如果编译器决定不实际内联对这些函数的任何调用,则不会对代码大小产生任何影响。如果编译器决定内联任何(或所有)调用,答案将是“它取决于”。对小函数的内联调用可能会导致代码大小增加和代码大小减小。这一切都取决于函数本身和编译器的能力(特别是优化能力)。

      【讨论】:

        【解决方案5】:

        如果函数的代码包含在头文件中,那么编译器可以使用它来为每个单独的源文件在目标代码中定义函数,或者将函数代码直接嵌入到调用函数的位置。根据您的编译器和链接器以及通常对 C++ 的支持,这可能会给您留下比单独定义的函数更大的代码。如果内联函数足够小,您可以通过避免函数调用开销来节省空间。但是,这样的函数必须非常小。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-06-14
          • 2018-12-03
          • 1970-01-01
          • 2019-02-16
          • 1970-01-01
          • 1970-01-01
          • 2012-03-06
          相关资源
          最近更新 更多