Я написал этот код:
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;
}
Вы путаете функцию inlining с разверткой цикла:
Разматывание петли означает преобразование
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 … (получающийся двоичный файл будет иметь несколько терабайт).
Встроенные функции вставляются только один раз за вызов.
В обоих ваших примерах встроенная функция вызывается только один раз, хотя она вызывается много раз.
Я считаю, что вы хотите что-то вроде этого:
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 раза в цикле и увеличит размер двоичного файла.
Примечание: отключите оптимизацию, потому что оптимизации могут привести к тому, что компилятор преобразует встроенную функцию в автономную функцию внутри цикла.