Вызовы, которые предшествуют определению функции, не могут быть встроенными?

документация gcc содержит следующее:

Когда функция является как встроенной, так и статической, если все вызовы
Функция интегрирована в вызывающего, и адрес функции
никогда не используется, то собственный код ассемблера функции никогда не будет
ссылки. В этом случае GCC фактически не выводит код ассемблера
для функции, если вы не укажете опцию
-fkeep-рядные функции. Некоторые вызовы не могут быть интегрированы по разным причинам (в частности, вызовы, предшествующие определению функции
не может быть интегрирован
, и ни один не может рекурсивные вызовы в пределах
определение).

Это всегда звучало абсурдно для меня — почему современный компилятор такой глупый? После быстрого теста это кажется неверным.

Тестовый код:

static inline int foo();

int bar() {
return foo();
}

int foo() {
return 42;
}

Результат с gcc-4.9.2 в Linux содержит код для bar() но не для foo(), Ты это видишь foo() был интегрирован:

bar:
.LFB0:
.cfi_startproc
movl    $42, %eax
ret
.cfi_endproc

Если я компилирую как C ++, результат будет таким же, за исключением искажения имени.

Вопреки документации, несмотря на foo() определяется после звонка в bar(), foo() был полностью интегрирован в bar(),

Я неправильно понимаю документацию или это неправильно? Возможно, это правильно для более сложного случая?

Я не знаю, есть ли техническое различие между «интегрировать» и «встроенный», но я подозреваю, что «интегрировать» используется, чтобы отличить от ключевого слова inline и это просто относится к встраиванию функции (отсюда и название).

Этот вопрос помечен как C и C ++, потому что эта часть документации gcc относится к «семейству языков C», и я ожидаю, что ответ будет одинаковым для двух языков.

9

Решение

Gcc использовал для компиляции и оптимизации по одной функции за раз, как только они были проанализированы, перед анализом следующей. IIRC, только в срок 4.X они представили -funit-at-a-time опция, которая откладывала оптимизацию после прочтения всего модуля компиляции, а затем они ждали некоторых выпусков, чтобы включить его по умолчанию.

Возможность встраивания функции, определенной после вызова, вероятно, была введена как часть -funit-at-a-time работа, и документация inline (упоминание о вызовах, предшествующих определению датируется, по крайней мере, до 2.95) тогда не обновлялось.

7

Другие решения


По вопросам рекламы [email protected]