Можно ли заставить функцию не быть встроенной? - PullRequest
47 голосов
/ 25 июля 2010

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

Ответы [ 8 ]

47 голосов
/ 25 июля 2010

В Visual Studio 2010, __declspec(noinline) говорит компилятору никогда не вставлять конкретную функцию-член, например:

class X {
     __declspec(noinline) int member_func() {
          return 0; 
     }
};

edit: Кроме того, при компиляции с /clr функции с атрибутами безопасности никогда не вставляются (опять же, это относится к VS 2010).

Я не думаю, что это вообще пригодится при отладке.

40 голосов
/ 25 июля 2010

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

__attribute__((noinline)) для gcc (и ряда менее распространенных компиляторов, которые поддерживают синтаксис атрибута gcc). Я должен признать, я не думаю, что когда-либо использовал это на самом деле, но, похоже, оно есть.

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

Я не уверен, как они взаимодействуют с ключевым словом inline C ++; Я использовал их только при отладке (когда я просто хочу, чтобы определенная не встроенная функция оставалась не встроенной после оптимизации) или при проверке сгенерированного кода (и я запутался, потому что вставляется случайный материал).

13 голосов
/ 25 июля 2010

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

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

Чтобы сайт вызова не был встроен, вы можете использовать указатель на функцию.

void (*f_ptr)(int); // pointer to function
volatile bool useMe = true; // disallow optimizations 
if (useMe)
   f_ptr = myFunc;
else
   f_ptr = useOtherFunc;

f_ptr(42); // this will not be inlined
4 голосов
/ 25 июля 2010

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

Когда речь идет об отладке стороннего кода ... да, это было бы полезно, особенно если вы можете убрать сторонний код изиздалека.Любой, у кого есть отлаженный код, содержащий большое количество разыменований shared_ptr, знает, о чем я говорю.

2 голосов
/ 25 июля 2010

Многие компиляторы могут выполнять кросс-трансляцию.В Visual Studio это было в течение пяти лет, и я считаю, что теперь GCC может это делать, особенно после того, как OP помечен как Visual C ++, и вполне справедливо, что его компилятор может справиться с этим.взять адрес функции, а затем сделать с ней что-то бессмысленное, например, вызвать его или передать в функцию ОС / внешней библиотеки.Компилятор не может встроить такую ​​функцию.

Зачем вам это нужно, IDK.

@ comments:

Если OP srsly, srsly нуждается в этом,затем он может скомпилировать его как lib и статически связать с ним.

1 голос
/ 25 июля 2010

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

0 голосов
/ 15 июня 2013

Если это функция-член класса, сделайте его виртуальным.

0 голосов
/ 25 июля 2010

Можно ли заставить функцию не быть встроенной?

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

Встраивание в основном является

  1. оптимизацией, которая в основном прозрачна для вас
  2. способ, позволяющий определять функции в заголовках без получения ошибок определения множества элементов

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...