inline
Inline — may relate to:* Inline citation or reference* Inline engine* Computers ** Inline expansion ** Inline function ** Inline assembler ** inline tag (HTML element)* Audio Equipment ** Inline adapter* Internet Posting Style ** Inline replying* Inline… … Wikipedia
Inline — Saltar a navegación, búsqueda Inline De izquierda a derecha Miguel Angel Castillo, Ivan Gutierrez, Alex Ibarra. Información personal Origen … Wikipedia Español
inline — 1923 of printing, 1929 of engines, 1958 of computers, by 1989 of roller skates; from IN (Cf. in) + LINE (Cf. line) … Etymology dictionary
inline — Оконтуренное начертание (Inline) Декоративное начертание, в котором каждый знак окружен контурной линией различной толщины. Таким образом, середина знака остается черной. В некоторых случаях наружная контурная линия окружает контурный знак,… … Шрифтовая терминология
Inline speed skating — is the sport of racing on inline skates. It is often called inline racing by participants. Although it primarily evolved from racing on quad roller skates, the sport is similar enough to ice speed skating that many competitors are now known to… … Wikipedia
Inline-Speedskating-World Games — Die World Games sind alle vier Jahre das wichtigste Ereigniss für die nicht olympische Sportart Inline Speedskating. Die Spiele werden von der International World Games Association − IWGA ausgerichtet. Rollschnelllauf (Rollschuhe) sowie das… … Deutsch Wikipedia
Inline skates — (often called by the trade name Rollerblade) are a type of roller skate used for inline skating. Unlike quad skates, which are configured with two front and two rear wheels, inline skates have two, three, four or five wheels arranged in a single… … Wikipedia
Inline-Skaterhockey-Bundesliga — Inline Skaterhockey Deutschland Die Inline Skaterhockey Bundesliga ist seit 1996 die höchste Spielklasse im deutschen Inline Skaterhockey. In der Bundesliga werden im Ligasystem, bei dem jeder Verein in Hin und Rückspielen gegen jeden anderen… … Deutsch Wikipedia
Inline figure skating — is figure skating on inline figure skates 3 or 4 wheel frames with a toe stop, mounted on figure skating boots in rockered configuration. Inline figure skating began as an off ice training alternative for ice figure skaters. The International… … Wikipedia
Inline-Downhill — ist eine Form des Inlineskatens bei welcher eine asphaltierte (Berg )Strecke heruntergefahren wird. Eine übliche Downhill Strecke hat ein durchschnittliches Gefälle von 7 bis 13 % und verfügt über mehrere Haarnadelkurven. Die… … Deutsch Wikipedia
Inline-Ersetzung — oder Inline Expansion ist eine Methode bei kompilierenden Programmiersprachen zur Steigerung der Ausführungsgeschwindigkeit des von ihnen erzeugten Codes, indem unnötige Aufrufe von (kurzen, einfachen) Unterprogrammen vermieden werden. Statt… … Deutsch Wikipedia
Что такое инлайн
![]()
Откройте возможности нейронного машинного перевода PROMT
PROMT.One — это облачное приложение – бесплатный онлайн-переводчик для перевода с языка на язык на основе нейронных сетей (Neural Machine Translation), словарь с транскрипцией, разговорники и многое другое. Наслаждайтесь правильным и точным переводом на английский, немецкий и еще 20+ языков.
Смотрите перевод слов и устойчивых выражений, транскрипцию и произношение в онлайн cловаре. Словари PROMT для английского, немецкого, французского, русского, испанского, итальянского и португальского языков включают миллионы слов и словосочетаний, самую современную разговорную лексику, которая постоянно отслеживается и пополняется нашими лингвистами.
Учите употребление слов и выражений в разных Контекстах. Миллионы реальных примеров на английском, немецком, испанском, французском помогут вам в изучении иностранных языков и подготовке домашних заданий.
Переводите в любом месте и в любое время с помощью бесплатного мобильного переводчика PROMT.One для iOS и Android. Попробуйте голосовой и фотоперевод.
Установите языковые пакеты для офлайн-перевода на мобильных устройствах и универсальный плагин PROMT АГЕНТ для Windows с подпиской PREMIUM.
Inline variables
Первоначальное назначение ключевого слова inline состояло в том, чтобы служить индикатором для оптимизатора, что встроенная подстановка функции предпочтительнее вызова функции, то есть вместо выполнения команды CPU для передачи управления в тело функции, копия тела функции выполняется без генерирования вызова. Эта оптимизация (inline expansion) основана на идее, что выполнение вызова функции является относительно дорогостоящим: оно требует перехода к новой подпрограмме, передачи аргументов функции и копирования возвращаемых значений. Inline expansion подавляет вызов функции путем копирования инструкций функции непосредственно в тело вызывающего объекта.
Последствия такой оптимизации в программе может быть очень трудно предвидеть. В дополнение к уменьшению накладных расходов на вызов функций, inline expansion позволяет выполнять широкий спектр дополнительных оптимизаций, которые в противном случае было бы очень трудно выполнить между вызовами функций. Однако не забывайте, что inline expansion создает копию тела функции для каждого вызова. Как следствие, помимо очевидного увеличения размера программы, дублирование инструкций делает программу кэш-недружественной.
Inline expansion может значительно повысить производительность, но это не точно. Производительность должна измеряться, а не предполагаться.
Т.к. программисты редко могут хорошо управлять оптимизациями, с них эта обязанность была снята, и современные компиляторы сами решают, когда применить inline expansion, а когда — не нужно.
Сегодня ключевое слово inline имеет мало общего с inline expansion. Эта оптимизация является необязательной для компилятора, компиляторы могут свободно использовать встроенную замену для любой функции, которая не помечена inline , и могут генерировать вызовы функций для любой функции, помеченной inline .
Однако ключевое слово inline затрагивает так же вопросы линковки. Подробнее про это можно почитать здесь. Поведение компилятора в вопросе оптимизаций не изменяет правила, касающиеся нескольких определений. Сегодня inline — это про one definition rule, а не про inline expansion оптимизацию. И поскольку значение ключевого слова inline для функций стало означать «разрешено несколько определений», а не» предпочтительно встроенное», это значение было распространено на переменные.
One definition rule и как его нарушить?
Функции и переменные, объявленные inline, могут быть определены в программе несколько раз.
Это, по сути, исключение из правила одного определения. ODR говорит, что вы можете определить только один раз функции, переменные, классы, перечисление и т. д.
ODR должен выполняться не только на уровне единицы трансляции, но и на уровне программы.
Встроенные функции и переменные являются исключением из правила одного определения: они могут быть определены несколько раз в программе (несколько раз в программе, но только единожды в одной единице трансляции).
Давайте рассмотрим пару примеров: использование inline при объявлении и инициализации глобальных констант и использование inline при объявлении и инициализации статических полей класса.
Глобальные константы
Часто определенные символьные константы могут быть использованы в разных частях программы (а не только в одном месте). Это могут быть физические или математические константы, которые не изменяются (например, число Пи или число Авогадро), или специфические для приложения значения (например, коэффициенты трения или гравитации). Вместо того чтобы переопределять эти константы в каждом файле, который нуждается в них, лучше объявить их один раз в одном месте и использовать везде, где это необходимо. Тогда, если вам когда-либо понадобится изменить их, вам нужно будет изменить их только в одном месте.
Немного про линковку
В единицу трансляции включены файл реализации (.c/.cpp) и все его заголовочные файлы (.h/.hpp).
Если внутри единицы трансляции у объекта или функции есть внутреннее связывание, то этот символ виден компоновщику только внутри этой единицы трансляции. Если же у объекта или функции есть внешнее связывание, то компоновщик сможет видеть его при обработке других единиц трансляции. Использование ключевого слова static в глобальном пространстве имен дает символу внутреннее связывание. Ключевое слово extern дает внешнее связывание.
Компилятор по умолчанию дает символам следующие связывания:
Non-const глобальные переменные — внешнее связывание;
Const глобальные переменные — внутреннее связывание;
Функции — внешнее связывание.
Глобальные константы как переменные с внутренним связыванием
Один из способов сделать это:
Создайте заголовочный файл для хранения этих констант.
Внутри этого заголовочного файла определите пространство имен.
Добавьте все ваши константы в пространство имен (убедитесь, что они constexpr).
#include вашего заголовочного файла везде, где это нужно.
И используйте ваши константы:
Когда этот заголовок включается ( #include ) в файл. cpp, каждая из переменных, определенных в заголовке, будет скопирована в этот cpp-файл в момент включения. Вы можете использовать эти константы в любом месте cpp-файла.
Поскольку эти глобальные константы имеют внутреннее связывание, каждый файл .cpp получает независимую версию глобальной константы. В большинстве случаев, компилятор соптимизирует их и подставит конкретные значения в местах использования.
Глобальные константы с внешним связыванием
Вышеприведенный метод имеет несколько потенциальных недостатков.Это легко использовать, но каждый раз, когда мы включаем заголвочный файл с константами в файл с кодом, каждая из этих переменных копируется в файл с кодом. Поэтому, если constants.h включается в 20 различных файлов кода, каждая из этих переменных дублируется 20 раз. Header guard не предотвратит это, так как она предотвращает только включение заголовка более одного раза в один cpp-файл, а не в несколько разных файлов с кодом. Это создает две проблемы:
Изменение одной константы потребует перекомпиляции каждого файла, используеющего константы, что делает компиляцию долгой для крупных проектов.
Если константы имеют большой размер и не могут быть оптимизированы, это приведёт к нежелательному расходу памяти.
Один из способов избежать этих проблем — обеспечить этим константами внешнее связывание, тогда мы сможем иметь единственную переменную (инициализированную один раз), которая является общей для всех единиц трансляции. Давайте определим константы в файле .cpp (чтобы гарантировать, что определения существуют только в одном месте) и запишем объявления в заголовочном файле (которые будут включены в другие cpp-файлы):
Можем использовать их:
Теперь константы будут создаваться только один раз (в constants.cpp), а не один раз каждый раз при включении constants.h, и все использования будут просто ссылаться на версию в constants.cpp. Любые внесенные изменения в constants.cpp потребуют только перекомпиляции constants.cpp.
Однако у этого метода есть несколько недостатков. Во-первых, эти константы теперь могут считаться константами времени компиляции только в файле, в котором они фактически определены (constants.cpp), а не где-либо еще. Это означает, что вне constants.cpp они не могут быть использованы нигде, где требуется постоянная времени компиляции. Во-вторых, оптимизировать их использование компилятору сложнее.
Учитывая вышеперечисленные недостатки, хочется определять константы в заголовочном файле.
Глобальные константы как inline переменные
C++17 ввел новую концепцию под названием inline variables. В C++ термин inline эволюционировал и стал означать “допускается несколько определений». Таким образом, встроенная переменная — это та переменная, которая может быть определена в нескольких файлах без нарушения ODR. Встроенные глобальные переменные по умолчанию имеют внешнее связывание.
Встроенные переменные имеют два основных ограничения, которые необходимо соблюдать:
Все определения встроенной переменной должны быть идентичны (в противном случае, это приведёт к неопределенному поведению).
Определение встроенной переменной должно присутствовать в любом файле, использующем переменную.
Компоновщик объединит все встроенные определения в одно определение переменной. Это позволяет нам определять переменные в заголовочном файле и обрабатывать их так, как если бы где-то в файле .cpp было только одно определение.
Перепишем наш пример следующим образом:
Мы можем включать constants.h в любое количество cpp-файлов, но эти переменные будут созданы только один раз и совместно использоваться во всех файлах с кодом.
Инициализация статических полей класса
Рассмотрим класс со статическим полем. В C++14 вам нужно сначала объявить его в классе:
А затем определить его в отдельном блоке компиляции:
В C++14 определение переменной в классе приведет к ошибке во время компиляции. Однако в C++17 можно так:
Определение вне класса также возможно:
Замечания
Ещё раз подчеркну: все определения встроенной функции или переменной во всей программе должны быть идентичны. Нарушение этого правила приведёт к неопределённому поведению.
Статическая переменная-член (но не переменная пространства имен), объявленная constexpr, неявно является встроенной переменной.
Но почему же мы не сталкиваемся с проблемами при определении функций в заголовочных файлах классов?
На самом деле для функций всё сказанное выше тоже актуально, но компилятор облегчает нам задачу, самостоятельно расставляя слово inline в нужных местах. А если точнее:
Функция, определенная полностью внутри определения класса/структуры/объединения, неявно является встроенной функцией.
Функция, объявленная constexpr, неявно является встроенной функцией.
Удаленная функция неявно является встроенной функцией: ее определение (=delete) может отображаться в нескольких единицах трансляции.
Ссылки
При подготовке статьи, кроме материалов, на которые я ссылался в тексте, использовались:
Данная статья была подготовлена экспертом OTUS — Анатолием Махаевым специально для студентов курса C++ Developer. Professional.
В преддверии старта курса, приглашаем всех желающих записаться на бесплатный демоурок по теме: «Полезные инструменты в разработке на С++».