Можно ли объявить метод встроенным методом, если в C ++ есть цикл for - PullRequest
1 голос
/ 23 октября 2009

У меня есть метод, подобный показанному ниже. Будет ли цикл for всегда делать компилятор для выполнения «встроенного запроса»?

inline void getImsiGsmMapFrmImsi
  (
    const string& imsiForUEDir, 
    struct ImsiGsmMap& imsiGsmMap
  )
{
    for (int i = 0 ; (unsigned)i < imsiForUEDir.length() - 1 ; i++)
    {
         imsiGsmMap.value[i] = imsiForUEDir[i] - '0' ;
    }
    imsiGsmMap.length = imsiForUEDir.length() - 1 ;
}

Ответы [ 6 ]

5 голосов
/ 23 октября 2009

Вы можете указать "inline", и компилятор может игнорировать его, если это так.

3 голосов
/ 23 октября 2009

Просто нет.

"inline" - это просто подсказка компилятору.

Есть способы заставить компилятор inline чем-то, но эти способы зависят от компилятора. Ваш код выглядит мобильным для меня, поэтому вот некоторые способы на некоторых компиляторах C ++, используемых на различных платформах мобильных телефонов:

Компилятор ARM в Windows CE / Windows Mobile VC ++ использует ключевое слово __forceinline вместо подсказки ' inline '.

Лучший компилятор (т. Е. Ускоряет вывод) для Windows CE / Windows Mobile - cegcc , в котором используется самая последняя версия GCC 4.4. В GCC вы пишете __attribute__((always_inline)) после имени функции и перед телом.

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

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

2 голосов
/ 23 октября 2009

«Нет вставки для функций с циклами», вероятно, является некоторой частью встроенной эвристики от определенного компилятора. Это не распространяется повсеместно.

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

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

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

0 голосов
/ 23 октября 2009

Подводя итог предыдущему ответу Я дал ему следующее, на что следует обратить внимание при выборе функции для встраивания:

* local static variables
* loop constructs
* switch statements
* try/catch
* goto
* recursion
* and of course too much complexity (whatever that means)

Сказав, что, как указывают другие ответы здесь, в основном не определено, включает ли компилятор функцию или нет. 7.1.2 / 2 имеет:

Объявление функции (8.3.5, 9.3, 11.4) со встроенным спецификатором объявляет встроенную функцию. Встроенный спецификатор указывает реализации, что внутренняя замена тела функции в точке вызова должна быть предпочтительнее обычного механизма вызова функции. Реализация не требуется для выполнения этой внутренней замены в точке вызова; тем не менее, даже если эта встроенная замена не указана, другие правила для встроенных функций, определенные в 7.1.2, должны соблюдаться.

Интересная деталь в том, что компилятор обычно маркирует тип поведения, который здесь задействован. Например: «не определено» или «поведение не определено» и т. Д.

0 голосов
/ 23 октября 2009

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

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

Но я бы не стал на это ставить.

0 голосов
/ 23 октября 2009

Интересно, нужно ли вообще встроенное ключевое слово? Разве современные компиляторы в основном просто игнорируют это и делают то, что считают лучшим?

...