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

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

48
задан Thomson 25 July 2010 в 12:36
поделиться

7 ответов

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

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

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

Однако я не думаю, что это окажется полезным при отладке.

50
ответ дан 26 November 2019 в 18:43
поделиться

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

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

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

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
13
ответ дан 26 November 2019 в 18:43
поделиться

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

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

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

@comments:

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

2
ответ дан 26 November 2019 в 18:43
поделиться

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

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

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

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

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

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

-12
ответ дан 26 November 2019 в 18:43
поделиться

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

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

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

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

43
ответ дан 26 November 2019 в 18:43
поделиться

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

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

4
ответ дан 26 November 2019 в 18:43
поделиться

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

0
ответ дан 26 November 2019 в 18:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: