Когда компиляторы встроены в код C ++?

В C ++ методы только вставляются, если они явно объявлены inline (или определены в заголовочном файле) или компиляторам разрешено встроить методы по своему усмотрению?

Да, компилятор может встроить код, даже если он явно не объявлен как inline .

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

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

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

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

И, вероятно, не рекомендуется определять функции, большие, чем, возможно, одну строку в заголовке, если вообще (плохо для времени компиляции, и если большая функция будет встроена, это может привести к раздуванию и ухудшению производительности).

Компиляторы могут встроить любую функцию или не включать ее. Им разрешено использовать inline украшение в качестве намека на это решение, но им также запрещено игнорировать его.

Также обратите внимание, что функции-члены classа имеют неявное inline украшение, если они определены в определении classа.

Компиляторы могут игнорировать вашу встроенную декларацию. Он в основном используется компилятором в качестве подсказки, чтобы решить, делать это или нет. Компиляторы не обязаны вставлять что-то, что помечено как встроенное, или не включать то, что нет. В основном вы находитесь во власти вашего компилятора и выбранного вами уровня оптимизации.

Если я не ошибаюсь, когда оптимизация включена, компилятор выполнит любую подходящую процедуру или метод.

Текст из информационного центра IBM ,

Использование встроенного спецификатора – это всего лишь предложение компилятору о том, что можно выполнить встроенное расширение; компилятор может игнорировать это предложение.

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

Функции C ++, реализованные внутри декларации classа, автоматически определяются встроенными. Регулярные функции C ++ и функции-члены, объявленные вне объявления classа, за исключением основного, могут быть объявлены или определены как встроенные с встроенным спецификатором функции. Статические локали и строковые литералы, определенные внутри тела встроенной функции, рассматриваются как один и тот же объект в единицах перевода;

Документация вашего компилятора должна сообщать вам, поскольку она зависит от реализации. Например, GCC в соответствии с его руководством никогда не строит код, если не будет применена оптимизация.

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

Компилятор оптимизируется по своему усмотрению, если вы не указали обратное.

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

Функции-члены объявляются встроенными по умолчанию. (Здесь также решает компилятор)

Это не жесткие и быстрые правила. Он зависит от реализации компилятора.

Если кто-то знает другие факторы, пожалуйста, напишите.

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

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

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

Некоторые из ситуаций, когда встроенное расширение НЕ работает:

  1. Для возвращающих функций, если существует цикл, коммутатор или goto
  2. Для функции, не возвращающей значения, если возвращается оператор return;
  3. Если функции содержат статические переменные
  4. Если встроенные функции являются рекурсивными.

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

(Как указано в одной из моих книг ООП)

  • Является ли уровень оптимизации -О3 опасным в g ++?
  • Как я могу ускорить свою программу Perl?
  • Отключить все опции оптимизации в GCC
  • Какие, если есть, компиляторы C ++ выполняют оптимизацию хвостовой рекурсии?
  • Что более эффективно? Используя pow для квадрата или просто умножьте его на себя?
  • Разница в скорости при использовании встроенных строк против конкатенации в php5?
  • Java Integer compareTo () - зачем использовать сравнение или вычитание?
  • Многопоточность имеет смысл для операций с привязкой к IO?
  • Распределение памяти / освобождение Узкое место?
  • ResultSet: получение значений столбцов по индексу по сравнению с извлечением по метке
  • Ускорить bitstring / bit операции в Python?
  • Interesting Posts

    Android Broadcast Receiver для отправленных SMS-сообщений?

    Генерация распределенного порядкового номера?

    Не удается извлечь внешний жесткий диск USB в Windows 10

    Node.js – Использование async lib – async.foreach с объектом

    Как получить сообщение об ошибке при сбое openstream

    Как открыть новое окно с помощью MVVM Light Toolkit

    Почему специальные символы, такие как «возврат каретки», представленный как «^ M»?

    Как скрыть или удалить адрес электронной почты из окна блокировки Windows 8?

    Как получить строку запроса из текущего URL-адреса с помощью JavaScript?

    Доступ к глобальному массиву за пределами связанного неопределенного поведения?

    Не удалось решить: com.google.firebase: firebase-core: 9.0.0

    Чтение значения с консоли в интерактивном режиме

    Ошибка сегментации в strcpy ()

    Предлагаемый критерий для тестирования загрузки процессора антивирусного программного обеспечения

    Почему GCC не использует частичные регистры?

    Давайте будем гением компьютера.