我有这些文件:
//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)
的多重定义答案 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
后,您将从之前的“一个定义规则”中删除豁免。