2013-07-20 3 views
2

В некоторых случаях я знаю, что явно определенная встроенная функция будет преобразована в обычную функцию с помощью стеков вызовов с помощью компилятора. Откуда я знаю, что это так? (для моего кода на C++)Как проверить встроенную функцию автоматически преобразуется в обычную функцию компилятором?

Кстати, в каких условиях компилятор преобразует встроенную функцию в обычную функцию?

+0

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

ответ

4

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

+1

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

+0

@ DavidRodríguez-dribeas Извините, но вы прочитали остальную часть моего ответа? «Это не означает, что он вообще не был встроен (возможно, что компилятор строит функцию, но также генерирует независимый объект функции, потому что, например, один присваивает ему указатель на функцию). Для этого вам нужно проверьте фактический сгенерированный код сборки ». –

+0

@ H2CO3 Так что 'nm' ничего вам не говорит.В моих тестах, даже с высокими уровнями оптимизации, символ всегда определялся независимо от того, были ли встроены вызовы функций. –

2

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

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

+0

+1 для проверки языка ассемблера. Это скажет, была ли функция включена или компилятор сгенерировал ветвь (вызов) функции. –

0

Компилятор будет ОПРЕДЕЛЕННО производить регулярную функцию, если встроенная функция имеет принятый адрес (то есть вы создаете для него указатель на функцию или что-то подобное). И, конечно, если функция virtual, она также должна существовать как отдельная функция, поскольку вызов функции virtual не всегда возможен.

Кроме этого, он полностью зависит от компилятора - он использует всевозможные эвристики, такие как «Насколько велика функция?», «Сколько раз это называется?», «Сколько« выигрыша » там от вставки его? ». Если функция вызывается много раз и достаточно велика, она, вероятно, остается автономной функцией. Если функция вызывается только несколько раз, или она крошечная, то она встроена [предполагается, что компилятор действительно МОЖЕТ вставить ее, конечно, как описано выше, возможно, она не сможет]. Кроме того, почти все компиляторы должны «видеть» исходный код функции, чтобы встроить эту функцию, но как GCC/G ++, так и MSVC имеют отношение к «оптимизации всей программы», предназначенное для преодоления этой проблемы.

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

Смежные вопросы