递归内联函数

时间:2010-09-05 19:27:44

标签: c++ inline recursive-query

我有这些文件:

//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 个答案:

答案 0 :(得分:1)

因为当你#include "Q2a.h"时,你基本上是对内容进行文本替换,所以Q2a.cpp和Q2b.cpp最终都定义了一个名为MyFactorial()的函数。您需要使用inline,或在其中一个源文件中定义该函数。

请注意,使用inline对递归函数没有多大帮助!

答案 1 :(得分:1)

GCC将函数声明为inline只会提示编译器内联函数。但是,编译器仍将生成可以从其他编译单元调用的非内联函数。

这些函数在您的情况下有名称冲突。简单地说:内联并不意味着静态。

您要做的是将函数声明为static inline

这将告诉编译您希望函数内联,并且 - 如果编译器决定内联它 - 不需要相同函数的静态版本。如果编译器无法内联函数,它将确保函数是静态的,例如,该函数的名称是C文件的本地名称,并且在链接程序期间不会发生名称冲突。

<强>提示:

编译器有不同的行为。如果您希望将来在其他平台上编译代码,请确保在宏中隐藏定义。

例如,我必须使用static inline作为GCC和Visual Studio,使用简单的_inline作为TI Code Composer DSP /嵌入式ARM编译器。后来的编译器不理解普通内联,因为它是非标准的,也不会理解静态_inline。

答案 2 :(得分:1)

当您声明函数inline时,您可以更改适用于函数定义的规则。

inline函数只能在程序中定义一次;相反,inline函数可以在多个翻译单元中定义,尽管定义必须相同,并且必须在使用它的每个翻译中定义函数。

删除inline后,您将从之前的“一个定义规则”中删除豁免。