【问题标题】:Why using inline function in c++ doesn't grow binary size?为什么在 C++ 中使用内联函数不会增加二进制大小?
【发布时间】:2013-03-09 18:24:28
【问题描述】:

我已经写了这段代码:

inline int a_plus_b_power2(int a, int b) {
  return (a + b) * (a + b); 
}

int main() {
  for(int a = 0; a < 9999999999999; ++a)
    for(int b = 0; b < 999999999999; ++b)
      a_plus_b_power2(a, b);  

  return 0;
}

但是为什么这个程序的二进制文件和这个程序没有区别:

inline int a_plus_b_power2(int a, int b) {
  return (a + b) * (a + b); 
}

int main() {
  for(int a = 0; a < 9; ++a)
    for(int b = 0; b < 9; ++b)
      a_plus_b_power2(a, b);  

  return 0;
}

【问题讨论】:

  • 我认为 OP 期望编译器生成 9999999999 * 99999999 (等)对内联函数的单独显式调用。
  • 999999999999 太大,无法放入 int。
  • @Inisheer 我希望编译器生成精确的 9999999999 * 99999999 单独副本,而不是调用。
  • 另外,由于您的结果被忽略,这两个都与int main() {return 0;} 完全相同,这就解释了为什么它们的大小相同。

标签: c++ inline-functions


【解决方案1】:

您将函数内联与循环展开混淆了:

循环展开表示变换

for (int i = 0; i < 4; i++)
  a(i);

进入

a(0); a(1); a(2); a(3);

函数内联表示变换

void a(int i) { cout << i; }

for (int i = 0; i < 4; i++)
  a(i);

进入

for (int i = 0; i < 4; i++)
  cout << i;

编译器确实有启用循环展开的选项(查看-funroll-loops 和 gcc 的相关选项),但除非你非常努力地戳它们,否则它们中的大多数将非常不愿意展开 999999999999 迭代......(生成的二进制文件将是数 TB)。

【讨论】:

  • 部分展开也没有那么复杂,每次迭代做 8 次之类的。
【解决方案2】:

内联函数每次调用仅“粘贴”一次。

在您的两个示例中,内联函数仅被调用一次,尽管它被多次调用。

我相信你想要这样的东西:

for (unsigned int a = 0; a < 9; ++a)
{
  for (unsigned int b = 0; b < 9; b+= 3) // Incremented by 3 because of 3 calls in loop.
  {
    a_plus_b_power_2(a, b + 0);
    a_plus_b_power_2(a, b + 1);
    a_plus_b_power_2(a, b + 2);
  }
}

上述示例可能会导致编译器在循环内将代码粘贴到内联函数中 3 次,并增加二进制文件的大小。

注意:关闭优化,因为优化可能会导致编译器将内联函数转换为循环内的独立函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多