рекурсивная встроенная функция - PullRequest
1 голос
/ 05 сентября 2010

у меня есть эти файлы:

//Q2a.h
#ifndef Q2A_H
#define Q2A_H

inline int MyFactorial(int a)
{
if (a < 2)
    return 1;
return a*MyFactorial(a-1);
}

int NumPermutations(int b);
#endif

//Q2a.cpp
#include "Q2a.h"

int NumPermutations(int b)
{
    return MyFactorial(b);
}

and file with the main- Q2b.cpp

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

g++ -Wall -g -c Q2a.cpp -o Q2a.o
g++ -Wall -g -c Q2b.cpp -o Q2b.o

это нормально, но на стадии соединения:

g++ -Wall -g -c Q2a.o Q2b.o -o Q2

я получаю ошибку: множественное определение `MyFactorial (int)

Ответы [ 3 ]

1 голос
/ 06 сентября 2010

Если GCC объявит функцию как inline, она просто намекает компилятору на встроенную функцию. Однако компилятор по-прежнему будет генерировать не встроенную функцию, которую вы можете вызывать из другого модуля компиляции.

Эти функции имели конфликт имен в вашем случае. Проще говоря: inline не подразумевает статичность.

Что вы хотите сделать, это объявить функции как static inline

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

Подсказка:

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

Например, я должен использовать static inline для GCC и Visual Studio и простой _inline для TSP Code Composer DSP / встроенного ARM-компилятора. Более поздний компилятор не понимает простой inline, потому что он нестандартный и не будет понимать static _inline.

1 голос
/ 06 сентября 2010

Когда вы объявляете функцию inline, вы изменяете правила, которые применяются для определений вашей функции.

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

Удаляя inline, вы удаляете исключение из «правила одного определения», которое у вас было ранее.

1 голос
/ 05 сентября 2010

Потому что, когда вы #include "Q2a.h", вы по сути делаете подстановку текста для содержимого, поэтому и Q2a.cpp, и Q2b.cpp в конечном итоге определяют функцию с именем MyFactorial().Вам нужно либо использовать inline, либо определить функцию в одном из исходных файлов.

Обратите внимание, что использование inline не очень поможет с рекурсивной функцией!

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