|
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
|
|
Inline функция или нет29.11.2017, 22:52. Показов 5917. Ответов 25
Метки нет (Все метки)
Как известно ключевое слово inline - это всего лишь просьба к компилятору оформить данную функцию как встраиваемую, а вот выполнит он эту просьбу или нет, ведомо только ему одному.
Вопрос такой, можно ли в принципе узнать удовлетворил ли он наше ходатайство о присвоении той или иной функции звания inline, или же он это ходатайство отклонил? И второй вопрос (если, конечно, ответ на первый будет положительным): Как это сделать в принципе?
0
|
|
| 29.11.2017, 22:52 | |
|
Ответы с готовыми решениями:
25
Inline функции - на сколько должна быть маленькая функция, чтоб она подошла под inline?
inline функция |
|
Вездепух
12937 / 6804 / 1821
Регистрация: 18.10.2014
Сообщений: 17,219
|
||
| 29.11.2017, 23:16 | ||
inline двояк. Это, во-первых, эффект для самой функции, и, во-вторых, эффект для вызовов этой функции.Встраивание кода функции в место вызова - это именно эффект второй группы. К самой функции он никакого отношения не имеет. Именно о встраивании вызовов вы ходатайствуете ключевым словом inline. Решение о встраивании/невстраивании кода в точке вызова принимается компилятором для каждого вызова отдельно и независимо. Какие-то вызовы могут встроиться, а какие-то - не встроиться. Узнать, какие вызовы встроились, а какие нет, можно только посмотрев на сгенерированный компилятором код. Более того, компилятор имеет полное право встраивать вызовы функций, не объявленных inline. То есть связь с inline тут очень нечеткая.Что касается эффекта для самой функции - он к встраиванию кода никакого отношения не имеет вообще. Эффект inline сводится только к тому, что для данной функции изменяется Правило Одного Определения (One Definition Rule): inline-функцию (в отличие от обычных функций) разрешается определять в программе несколько раз, в разных единицах трансляции. Здесь нет никакого "ходатайства" - это эффект всегда проявляется гарантированно и безусловно.То есть "звание inline" такая функция получает всегда и безусловно. Но это не гарантирует, что все вызовы этой функции будут встраиваться. Может быть вообще ни один не встроится.
1
|
||
|
Заклинатель змей
705 / 560 / 219
Регистрация: 30.04.2016
Сообщений: 2,605
|
|
| 29.11.2017, 23:20 | |
|
Просто Саша, присоеденюсь к мнениюTheCalligrapher. Если верить Шилдту, то встраивания нет для функций с if/else, for, goto
0
|
|
|
Вездепух
12937 / 6804 / 1821
Регистрация: 18.10.2014
Сообщений: 17,219
|
||
| 29.11.2017, 23:31 | ||
|
Проблемы с встраиванием также могут быть у функций, содержащих вызовы alloca, setjmp/longjmp. Помнится были еще какие-то менее очевидные проблемы с обработкой исключений.Но "if/else, for, goto" - это из разряда "это было давно и неправда"... Добавлено через 4 минуты Многие компиляторы, кстати, предоставляют средства для отслеживания того, встроились ли вызовы inline функций. Для GCC это предупреждение выключается через -Winline. Для MSVC, насколько я помню, аналогичные предупреждения генерируются для __forceinline функций.
1
|
||
|
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
|
||
| 29.11.2017, 23:39 [ТС] | ||
|
Коли сделали мы функцию inline функцией, то все, во-первых мы распрощались с ее прототипами, и обязаны размещать определение такой функции выше по тексту в том файле, куда мы хотим ее пристроить. А что там делает компилятор - это интересно, я и задал то поэтому вопрос, можно или нет оценить как сработал компилятор в том или в другом случае. Добавлено через 6 минут Кстати, хочу обратить внимание не на вот эти else и goto, а вот на такой факт: В учебниках напрочь отсутствует такая тема inline функции и перегрузка. Вот что Вы можете сказать по этому поводу? Вот согласитесь, что вот так с ходу не определишь, разрешается ли перегружать inline функцию, а если разрешается, то как встраивается то или другое. Ведь на стадии компиляции не очень то определишь, что будет вызвано на стадии выполнения.
0
|
||
|
Вездепух
12937 / 6804 / 1821
Регистрация: 18.10.2014
Сообщений: 17,219
|
|||
| 29.11.2017, 23:48 | |||
inline), а определение поместить вниз.
1
|
|||
|
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
|
|||||||||||
| 29.11.2017, 23:52 [ТС] | |||||||||||
|
Кстати вот Стивен Прата в своем учебнике утверждает, что для того чтобы функция стала inline нужно выполнить хотя бы одно из двух:
1) Предварить ОПРЕДЕЛЕНИЕ этой функции словом inline 2) Предварить ОБЪЯВЛЕНИЕ этой функции словом inline (я так понимаю это использовать прототип с inline) Возникает вопрос зачем использовать inline с прототипом, если определение должно стоять выше по тексту. Или он что имеет в виду, что inline функцию можно разместить в отдельном файле, а затем дотянуться до нее просто использовав inline с ее прототипом. Попробовал и вот что вышло: 1) вариант
2) вариант (inline уже только в прототипе)
0
|
|||||||||||
|
Вездепух
12937 / 6804 / 1821
Регистрация: 18.10.2014
Сообщений: 17,219
|
|||||||||
| 30.11.2017, 00:00 | |||||||||
1
|
|||||||||
|
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
|
|
| 30.11.2017, 00:22 [ТС] | |
|
Ну почему он не должен появляться на уровне блока, если во-первых тоже работает, а во-вторых, зачем он на внешнем, если он нужен только в функции main?
Куда тогда деть принцип минимальных привилегий? И опять же самый главный вопрос. Ну работает оно и в моем и в Вашем варианте и проверил будет работать даже если функцию display разместить в отдельном файле. Но то что имеет место inline не факт. Может оно сработало, как вызов обычной функции, хотя по всем канонам, вот такая функция просто обязана быть встраиваемой.
0
|
|
|
Вездепух
12937 / 6804 / 1821
Регистрация: 18.10.2014
Сообщений: 17,219
|
|||||||||||||||
| 30.11.2017, 00:38 | |||||||||||||||
inline, то он своею задачу выполнил - вас предупредил. А дальше - ваши проблемы. С точки зрения С++ поведение программы не определено.А если ваш компилятор вообще никак не ругнулся, то это значит, что либо вы его неправильно сконфигурировали (т.е. он не работает в режиме стандартного С++ вообще), либо в компиляторе сидит баг. GCC исправно ругается на такое: http://coliru.stacked-crooked.... bf0c1dad6b
inline, то она должна быть определена в этой же единице трансляции. А то, что "будет работать если разместить в отдельном файле" - это уже глюки реализации, к С++ никакого отношения не имеющие.
1
|
|||||||||||||||
|
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
|
|
| 30.11.2017, 01:02 [ТС] | |
|
Никак он не ругается и никаких предупреждений не дает (MS Visual Studio 2017)
Что значит снаружи? В C++ все функции определяются снаружи, но это ведь не значит, что доступ к ним нужно давать везде, где только можно. Так мы докатимся и до того, что все переменные глобальными сделаем. Ну каноны такие - функция всего одна строка, да и то простейшая, конечно я тут на уровне интуиции говорю. Ну а что на самом деле, если эта простота не inline, то что тогда вообще может быть inline? Вот пока, что понял, так это то, что inline дает возможность размещать такие функции в заголовках, а все остальное на уровне любит - не любит, или, как говорится - ОТ ЛУКАВОГО. Добавлено через 3 минуты Самое то главное не сделано. Ну понятно, компилятор сработает, как написали его разработчики, следовали они стандарту или не следовали - это другой вопрос. Понятно, что нельзя требовать от программы (компилятора), чтобы он сделал что-то сверх того, что в него вложили, но вот что конкретное он сделал (обинлайнил он эту функцию или же нет) мы вроде знать имеем право. Но тут то как раз везде, что в учебниках, что в сети, тишина глухая, как на кладбищенском погосте. Добавлено через 4 минуты Да и еще вот нарыл, что #pragma inline-recursion позволяет инлайнить и рекурсивные функции до 16 уровней. Ещё какая-то прагма позволяет понижать число этих уровней. И не будут инлайнится те функции, обращение к которым происходит через указатель.
0
|
|
|
Вездепух
12937 / 6804 / 1821
Регистрация: 18.10.2014
Сообщений: 17,219
|
|||||
| 30.11.2017, 01:52 | |||||
private и protected на уровне класса и static/unnamed namespace на уровне единицы трансляции, но это не наша тема.Запустите GCC с -Winline - и он сам будет объяснять вам, почему он что-то не заинлайнил.
2
|
|||||
|
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
|
|
| 30.11.2017, 02:04 [ТС] | |
|
Нет, тут до связывания дело не доходит. Оно здесь вообще ни сбоку припеку и правильно Вы говорите - это не наша тема.
Локальных функций, конечно нет, зато есть локальные области видимости. Вот последнее более интересно, значит все таки, кто то реализовал такую штуку. Тогда разумеется вопрос сужается. Вы может быть знаете тогда какой ключ в MS Visual Studio отвечает за подобную функциональность?
0
|
|
|
Вездепух
12937 / 6804 / 1821
Регистрация: 18.10.2014
Сообщений: 17,219
|
|||||||
| 30.11.2017, 04:08 | |||||||
__forceinline вместо inline, а также включить предупреждение C4714 (уровень 4). То есть либо поднять уровень предупреждений в настройках проекта до 4, либо наоборот понизить собственный уровень C4714 до 1
C4714 на вызовы __forceinline функций, которые он по какой-то причине не сумел встроить. Объяснений "почему" он однако не предоставляет - надо разбираться самому.В описании C4714 перечислены возможные причины.
1
|
|||||||
|
Велосипедист...
353 / 220 / 73
Регистрация: 15.12.2015
Сообщений: 785
|
|||||||||||
| 30.11.2017, 04:18 | |||||||||||
|
Пока мы еще совсем не съехали с темы, хочу воспользоваться моментом и уточнить 2 вещи:
1. Правда ли, что ключевое слово inline можно опустить в определении inline-функции, если выше есть объявление ( прототип ) этой функции?
inline? У меня сейчас двоякое мнение:__1) с одной стороны, это UB, ведь если компилятор действительно встроит такую функцию, тогда ее существовать не будет в принципе. __2) с другой стороны, как мне кажется, если компилятор встретит выражение, где адрес функции ( которую пометили как inline ) попытаются присвоить указателю на функцию, то такая функция встроенной не станет ( спецификатор inline будет проигнорирован ).
TheCalligrapher
0
|
|||||||||||
|
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
|
||
| 30.11.2017, 04:35 | ||
|
1
|
||
|
Велосипедист...
353 / 220 / 73
Регистрация: 15.12.2015
Сообщений: 785
|
|
| 30.11.2017, 04:39 | |
|
Renji, Это так есть на самом деле, или это Ваше предположение?)
0
|
|
|
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
|
||
| 30.11.2017, 04:40 | ||
|
1
|
||
|
Вездепух
12937 / 6804 / 1821
Регистрация: 18.10.2014
Сообщений: 17,219
|
|||
| 30.11.2017, 04:41 | |||
|
Вы продолжаете путать две вещи, о которых я говорил ранее: влияние inline на саму функцию и влияние inline на вызовы этой функции в коде.На саму функцию inline влияет только одним образом: он позволяет определять ее много раз в программе (без возникновения при этом ошибки линкера). Этот эффект inline есть всегда, то есть ни о каком игнорировании inline не может быть и речи. К "указателям" это не имеет никакого отношения.Что касается вызовов (и других ссылок) на функцию из основного кода - то это совсем другая история. Одни вызовы могут быть встроены, другие - не встроены. Если какие-то вызовы отказались не встроены, то для обслуживания таких вызовов компилятором будет сгенерировано обычное тело той же самой функции, единственное на всю программу. Вот точно так же и с указателями: если где-то в коде кто-то создает указатель на inline функцию, то по этой причине будет сгенерировано обычное тело функции и этот указатель будет указывать на него. Это однако никак не мешает остальным вызовам этой функции продолжать спокойно встраиваться Таким образом никакого UB тут нет. И никакого игнорирования inline тут тоже нет. Что с указателями, что без, все работает по одной и той же схеме. В каждой точке кода решение принимается индивидуально: если компилятор захотел/сумел выполнит встраивание, он его выполняет, а в остальных случаях идет работа с обычным телом функции. В том числе, если в месте вызова функции через указатель "особо умный" компилятор точно знает, на какую функцию этот указатель указывает, то он может сделать прямой вызов и выполнить встраивание. Эта логика распространяется и на объявление виртуальных функций как inline.
1
|
|||
|
Велосипедист...
353 / 220 / 73
Регистрация: 15.12.2015
Сообщений: 785
|
|||
| 30.11.2017, 05:06 | |||
|
Спасибо.
0
|
|||
| 30.11.2017, 05:06 | |
|
Помогаю со студенческими работами здесь
20
Inline функция в Debug режиме virtual inline функция-член каласса inline функции vs инструкции inline функций Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Символьное дифференцирование
igorrr37 13.02.2026
/ *
Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет
значение производной при заданном х
Логарифм записывается как: (x-2)log(x^2+2) -. . .
|
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
|
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу,
и светлой Луне.
В мире
покоя нет
и люди
не могут жить в тишине.
А жить им немного лет.
|
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила»
«Время-Деньги»
«Деньги -Пуля»
|
|
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога
Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
|
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога
Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
|
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога
Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
|
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
|