При возникновении проблем при связывании программы с неопределенными символами [duplicate]

Также вы можете использовать:

inflater.getContext();

, но я бы предпочел использовать

getActivity()

или

getContext
62
задан Pwnna 12 May 2011 в 00:32
поделиться

6 ответов

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

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

78
ответ дан Greg Hewgill 18 August 2018 в 22:33
поделиться
  • 1
    Я думал, что цель inline заключается в том, чтобы компилятор «расширил» содержимое функции, где он вызывается, поэтому не будет vtable lookup (или переход команды к функции на уровне CPU). – DJ. 12 May 2011 в 00:41
  • 2
    Является ли ваш первый пункт [полезным] побочным эффектом по назначению? – Ian Fleeton 12 May 2011 в 00:50
  • 3
    @Ian Fleeton: Это действительно побочный эффект; если у встроенного идентификатора не было области файла, тогда было бы невозможно установить определение встроенной функции в файл заголовка. – Greg Hewgill 12 May 2011 в 00:52
  • 4
    @Greg: На самом деле это не так, как static. Если бы это было так, каждая единица перевода имела бы свою собственность над своей копией функции, и компоновщик рассматривал бы их как разные функции (которые имели одно и то же имя). Напротив, inline инструктирует компоновщика, что, если он видит различные определения этой функции, они все одинаковы и должны быть объединены в один. Но игнорируя эту деталь, она, по большей части, ведет себя так, как если бы она была static. – GManNickG 12 May 2011 в 00:54
  • 5
    @DJ: inline не может предотвратить поиск vtable, вам нужно вызвать девиртуализацию для этого. – Ben Voigt 12 May 2011 в 00:54

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

20
ответ дан Ben Jackson 18 August 2018 в 22:33
поделиться
  • 1
    Имеет смысл, я пошел от справки и 10-летнего опыта. – Ian Fleeton 12 May 2011 в 00:42

Да, есть разница. https://isocpp.org/wiki/faq/inline-functions .

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

void myfunc() {
  square(2);
}

идентичен

void myfunc() {
   2 * 2;
}

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

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

27
ответ дан Default 18 August 2018 в 22:33
поделиться
  • 1
    Я думаю, что с помощью gcc вы можете использовать флаг компиляции -Winline, чтобы предупредить, когда функция не будет встроена. И вы могли бы объединить это с -Werror, если вы массачист. – patmanpato 21 February 2016 в 22:38

inline хорошо работает с концепцией процедурной абстракции :

inline double square (double x) { return x*x;}

int squareTwice(double x) {
    double first = square(x);
    double second = square(x);
    return first * second; 
}

Вышеупомянутое в корне похоже на следующее:

int squareTwice(double x) {
    double first = x*x;
    double second = x*x;
    return first * second; 
}

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

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

2
ответ дан Gio Borje 18 August 2018 в 22:33
поделиться

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

2
ответ дан Ian Fleeton 18 August 2018 в 22:33
поделиться
  • 1
    Компилятор не должен включать функцию, если она не хочет, даже если указано ключевое слово inline. – Marlon 12 May 2011 в 00:40
  • 2
    @Alex Marlon не сказал, что компилятор не будет встраивать функцию, просто чтобы ей не приходилось . Это очень разные вещи. – anthropomorphic 14 August 2014 в 04:14

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

http://en.wikipedia.org/wiki/Inline_function

5
ответ дан johannesMatevosyan 18 August 2018 в 22:33
поделиться
Другие вопросы по тегам:

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