Неопределенная ссылка со встроенной функцией c ++ - PullRequest
2 голосов
/ 26 января 2020

У меня есть два cpp файла:

F1. cpp

using namespace std;

int i;

void Modify();

int main()
{
 i=1;
 cout << "i main 1 = " << i << endl;
 Modify();
 cout << "i main 2 = " << i << endl;

 return 0;
}

F2. cpp

using namespace std;

extern int i;

inline void Modify()
{

  i=99;

  cout << "i modify = " << i << endl;

}

Когда я запускаю исполняемый файл, я получаю эту ошибку: F1.o: В функции main: F1. cpp :(. Text + 0x4a): неопределенная ссылка на `Modify () 'collect2 : ошибка: ld вернул 1 состояние выхода

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

Пожалуйста, помогите!

Ответы [ 3 ]

3 голосов
/ 26 января 2020

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

Из стандарта C ++ 17 (10.1.6 встроенный спецификатор)

2 Объявление функции (11.3.5, 12.2.1, 14.3) со встроенным спецификатором объявляет встроенную функцию. Встроенный спецификатор указывает реализации, что внутренняя замена тела функции в точке вызова должна быть предпочтительнее обычного механизма вызова функции. Реализация не требуется для выполнения этой внутренней замены в точке вызова; однако, даже если эта встроенная подстановка опущена, другие правила для встроенных функций, указанные в этом разделе, все равно должны соблюдаться.

и

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

1 голос
/ 26 января 2020
void Modify();

Эта строка фактически является функцией объявление . Однако вы не предоставили реализацию функции (т. Е. Определение функции). Вы определили встроенную функцию в F2. cpp, но это не видно в F1. cpp. Если он был определен в заголовке и этот заголовок включен в F1. cpp, тогда у вас не будет этой проблемы.

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

Этот раздел C ++ FAQ интересен:

Примечание. Обязательно, чтобы определение функции (часть между {...}) было помещено в заголовочный файл, если только функция не используется только в одном файле. cpp. В частности, если вы поместите определение встроенной функции в файл. cpp и вызовете его из другого файла. cpp, вы получите «неразрешенную внешнюю» ошибку от компоновщика.

1 голос
/ 26 января 2020

В вашем файле F1. cpp значение Modify() фактически никогда не определялось. Это также относится к возвращаемой ошибке.

...