Время, когда встроенное функционирование не может быть использовано - PullRequest
6 голосов
/ 05 июля 2011

Я изучаю встроенные функции в C ++ и пришел к разделу, касающемуся ограничений его использования.В нем говорится:

Компилятор также не может выполнить встраивание, если адрес функции взят неявно или явно.

Может кто-нибудь объяснить мне, возможно, с примеромкакой-то, что именно это означает?

Ответы [ 3 ]

6 голосов
/ 05 июля 2011

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

Фактическая встроенная часть зависит от компилятора.Он может игнорировать ваш запрос, если, например, ваша функция является рекурсивной или слишком длинной.С другой стороны, компилятор может выбрать встроенную функцию, которую вы на самом деле не пометили как встроенную.

5 голосов
/ 05 июля 2011

Есть два отдельных решения, которые компилятор принимает в отношении встраивания функций:

  • является ли конкретный вызов функции встроенным;
  • существует ли не встроенная версия функции.

Первое определяется компилятором в каждом конкретном случае, если в этот момент возможно встраивание. Это не будет возможно, если функция является виртуальной или вызывается через указатель функции, и она не может определить во время компиляции, какая функция должна быть вызвана. Это будет невозможно, если определение не доступно компилятору, возможно, потому что оно определено в другом модуле перевода, и компилятор не выполняет «оптимизацию всей программы». Решение может или не может зависеть от того, объявлена ​​ли функция inline и других факторов, таких как ее размер и как часто она вызывается.

Второе зависит от того, требуется ли не встроенная версия. Это будет необходимо, если какой-либо вызов к нему не является встроенным. Это также (согласно вашей цитате) потребуется, если что-либо нуждается в адресе функции, так как тогда у него должен быть адрес. Это может происходить либо напрямую (например, путем присвоения адреса указателю функции), либо косвенно (например, виртуальным функциям потребуется, чтобы их адрес где-то сохранялся для поиска во время выполнения в соответствии с динамическим типом объекта).

Наличие не встроенной версии не помешает конкретному вызову функции быть встроенным, хотя возможно, что это может повлиять на решение компилятора, особенно если он настроен на оптимизацию под размер кода.

Подводя итог, ваша цитата является упрощенной и не совсем точной; компилятор все еще может «выполнить вставку», если адрес взят, он просто не может опустить не встроенную версию.

4 голосов
/ 05 июля 2011

Это просто неправильно: на способность встроить вызов функции не влияют вычисления 2 + 2 или взятие адреса функции куда-либо.

Какую книгу или статью вы читаете?

С другой стороны, если адрес взят, то может быть практически невозможно удалить отдельную функцию машинного кода.

Приветствия & hth.,

...