为什么在 c++ 中使用内联函数不会增加二进制大小?

Why using inline function in c++ doesn't grow binary size?

本文关键字:增加 二进制 函数 c++ 为什么      更新时间:2023-10-16

我写了下面的代码:

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;
}

你混淆了函数内联和循环展开:

循环展开意味着转换

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)。

内联函数每次调用只"粘贴"一次。

在你的两个例子中,内联函数只被调用一次,尽管它被调用了很多次。

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

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次,并增加二进制文件的大小。

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