изменение связи встроенной функции - PullRequest
4 голосов
/ 16 ноября 2011

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

#include <iostream>
using namespace std;
inline int f1(int a,int b){
  a=a+b;
  while(a!=0)
    a--;
  cout<<"inline";
  return a;
}

второй:

int main(){
  extern void f1(int a,int b);
  f1(1,2);
}

g ++ frist.cc second.cc

undefined reference to `f1(int, int)'

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


но, когда я добавляю функцию вызовавстроенной функции для первого файла:

#include <iostream>
using namespace std;
inline int f1(int a,int b){
  a=a+b;
  while(a!=0)
    a--;
  cout<<"inline";
  return a;
}
int callf1(){
  f1(10,2);
}

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

Ответы [ 2 ]

5 голосов
/ 16 ноября 2011

что здесь произошло?

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

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

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

4 голосов
/ 16 ноября 2011

В C ++, если функция определена как inline где-то, так должно быть везде

из C ++ 7.1.2

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

3,2 относится к правилу единого определения

Итак, вы испытываете не стандартное поведение C ++

...