Встроенные функции C ++ с использованием GCC - почему CALL? - PullRequest
17 голосов
/ 01 июня 2009

Я тестировал вызовы встроенных функций в C ++.

Thread model: win32
gcc version 4.3.3 (4.3.3-tdm-1 mingw32)

Страуструп на языке программирования C ++ wirtes:

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

Однако я обнаружил, что сгенерированный код просто не встроен. Для функции isquare существует CALL .

alt text

Почему это происходит? Как я могу использовать встроенные функции тогда?

РЕДАКТИРОВАТЬ: Используемые параметры командной строки:

**** Build of configuration Debug for project InlineCpp ****

**** Internal Builder is used for build               ****
g++ -O0 -g3 -Wall -c -fmessage-length=0 -osrc\InlineCpp.o ..\src\InlineCpp.cpp
g++ -oInlineCpp.exe src\InlineCpp.o

Ответы [ 7 ]

47 голосов
/ 01 июня 2009

Как упоминал Майкл Коне, ключевое слово inline всегда является подсказкой, и GCC в случае вашей функции решил не вставлять его.

Поскольку вы используете Gcc, вы можете принудительно встроить __attribute ((always_inline)).

Пример:

 /* Prototype.  */
 inline void foo (const char) __attribute__((always_inline));

Источник: Встроенные документы GCC

22 голосов
/ 01 июня 2009

Не существует универсального способа C ++ для FORCE компилятора для создания встроенных функций. Обратите внимание на слово «подсказка» в цитируемом вами тексте - компилятор не обязан вас слушать.

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

РЕДАКТИРОВАТЬ: njsf дает правильное ключевое слово gcc в своем ответе.

8 голосов
/ 01 июня 2009

Вы ищете отладочную сборку (оптимизации отключены)? Компиляторы обычно отключают встраивание в "отладочных" сборках, потому что они затрудняют отладку.

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

  • Компилятор может быть простым и не поддерживать встраивание
  • Компилятор может использовать внутренний алгоритм, чтобы решить, что встроить, и игнорировать подсказки.
    (иногда компилятор может выполнять лучшую работу, чем вы, возможно, делаете при выборе встроенного, особенно в сложных архитектурах, таких как IA64) Компилятор может использовать собственную эвристику, чтобы решить, что, несмотря на подсказку, встраивание не улучшит производительность
4 голосов
/ 01 июня 2009

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

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

3 голосов
/ 01 июня 2009

Это подсказка, и компилятор может игнорировать подсказку. Я думаю, что читал кое-что, где этот GCC вообще игнорирует это. Я помню, слышал, что был флаг, но он все еще не работает в 100% случаев. (Я еще не нашел ссылку).

Флаг: -finline-functions включен на уровне оптимизации -O3.

0 голосов
/ 01 июня 2009

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

0 голосов
/ 01 июня 2009

Инлайн ли зависит от компилятора. Можно ли игнорировать подсказку inline . У некоторых компиляторов есть определенное ключевое слово (например, __forceinline в VC ++), но даже с таким ключевым словом виртуальные вызовы виртуальных функций-членов не будут встроены.

...