递归内联函数

发布于 2024-09-17 23:18:35 字数 598 浏览 6 评论 0原文

我有这个文件:

//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) 的多重定义

i have this files:

//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

i notice that the compiler usually ignore the inline decleration when there are recursive functions .
but my question is why if i remove the inline declaration, i can do:

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

those are fine, but in the linkage stage:

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

i get an error: multiple definition of `MyFactorial(int)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

远昼 2024-09-24 23:18:35

因为当您 #include "Q2a.h" 时,您实际上是在对内容进行文本替换,因此 Q2a.cpp 和 Q2b.cpp 最终都会定义一个名为 MyFactorial( )。您要么需要使用内联,要么在源文件之一中定义该函数。

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

Because when you #include "Q2a.h", you're essentially doing a text substitution of the contents, so both Q2a.cpp and Q2b.cpp end up defining a function called MyFactorial(). You either need to use inline, or define the function in one of the source files.

Note that using inline won't help very much with a recursive function!

茶色山野 2024-09-24 23:18:35

使用 GCC 将函数声明为内联函数只会提示编译器内联该函数。但是,编译器仍然会生成一个非内联函数,您可以从不同的编译单元调用该函数。

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

您想要做的是将函数声明为静态内联,

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

提示:

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

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

With GCC declaring a function as inline will just hint the compiler to inline the function. However, the compiler will still generate a non-inline function that you can call from a different compilation unit.

These functions had a name collision in your case. Simply said: inline doesn't imply static.

What you want to do is to declare the functions as static inline

This will tell the compile that you want your function inline, and - if the compiler decides to inline it - no static version of the same function is required. It otoh the compiler can't inline the function it will make sure that the function is static, e.g. the name of the function is local to the C-file and no name collisions during linking of the program will occur.

Hint:

Compilers have different behaviour. If you want to compile the code on a different platform in the future make sure that you hide the definition in a macro.

For example I have to use static inline for the GCC and Visual Studio and a simple _inline for the TI Code Composer DSP/embedded ARM compiler. The later compiler doesn't understand a plain inline because it is non-standard and won't understand static _inline either.

剪不断理还乱 2024-09-24 23:18:35

当您声明函数内联时,您更改了适用于函数定义的规则。

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

通过删除内联,您将删除之前的“一个定义规则”的豁免。

When you declare a function inline you change the rules that apply for the definitions of your function.

A non-inline function must only be defined once in a program; in contrast an inline function may be defined in multiple translation units, although the definitions must be identical and the function must be defined in every translation in which it is used.

By removing inline, you are removing the exemption from the "one definition rule" that you had previously.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文