C语言 .c 文件中的 C99 内联函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16245521/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 06:11:19  来源:igfitidea点击:

C99 inline function in .c file

cc99

提问by user14416

I defined my function in .c (without header declaration) as here:

我在 .c 中定义了我的函数(没有头声明),如下所示:

inline int func(int i) {
 return i+1;
}

Then in the same file below I use it:

然后在下面的同一个文件中我使用它:

...
i = func(i);

And during the linking I got "undefined reference to 'func'". Why?

在链接期间,我得到了“对‘func’的未定义引用”。为什么?

回答by Jens Gustedt

The inlinemodel in C99 is a bit different than most people think, and in particular different from the one used by C++

inlineC99 中的模型与大多数人想象的有点不同,特别是与 C++ 使用的模型不同

inlineis only a hint such that the compiler doesn't complain about doubly defined symbols. It doesn't guarantee that a function is inlined, nor actually that a symbol is generated, if it is needed. To force the generation of a symbol you'd have to add a sort of instantiation afterthe inlinedefinition:

inline只是一个提示,以便编译器不会抱怨双重定义的符号。如果需要,它不保证函数是内联的,也不保证实际上生成符号。要强制生成符号,您必须在定义添加一种实例化inline

int func(int i);

Usually you'd have the inlinedefinition in a header file, that is then included in several .c files (compilation units). And you'd only have the above line in exactly one of the compilation units. You probably only see the problem that you have because you are not using optimization for your compiler run.

通常你会inline在一个头文件中有定义,然后包含在几个 .c 文件(编译单元)中。并且您只会在编译单元之一中包含上述行。您可能只会看到您遇到的问题,因为您没有对编译器运行进行优化。

So, your use case of having the inlinein the .c file doesn't make much sense, better just use staticfor that, even an additional inlinedoesn't buy you much.

因此,您inline在 .c 文件中使用 的用例没有多大意义,最好仅用于此目的static,即使是额外的inline也不会给您带来太多好处。

回答by Christoph

C99 inline semantics are often misunderstood. The inlinespecifier serves two purposes:

C99 内联语义经常被误解。在inline符有两个目的:

First, as a compiler hint in case of static inlineand extern inlinedeclarations. Semantics remain unchanged if you remove the specifier.

首先,作为static inlineextern inline声明的编译器提示。如果删除说明符,语义将保持不变。

Second, in case of raw inline(ie without staticor extern) to provide an inline definition as an alternative to an external one, which has to be present in a different translation unit. Not providing the external one is undefined behaviour, which will normally manifest as linking failure.

其次,在 raw inline(即没有staticextern)的情况下,提供内联定义作为外部定义的替代,外部定义必须存在于不同的翻译单元中。不提供外部是未定义的行为,通常表现为链接失败。

This is particularly useful if you want to put a function into a shared library, but also make the function body available for optimization (eg inlining or specialization). Assuming a sufficiently smart compiler, this allows you to recover many of the benefits of C++ templates without having to jump through preprocessor hoops.

如果您想将一个函数放入共享库,同时又使函数体可用于优化(例如内联或特化),这将特别有用。假设编译器足够智能,这允许您恢复 C++ 模板的许多好处,而无需跳过预处理器。

Note that it's a bit more messy than I described here as having another file scope non-inline external declaration will trigger the first case as described in Jens' answer, even if the definition itself is inlineinstead of extern inline. This is by design so you can have have a single inline definition in a header file, which you can include into the source file that provides the external one by adding a single line for the external declaration.

请注意,它比我在此处描述的更混乱,因为具有另一个文件范围的非内联外部声明将触发 Jens 的回答中所述的第一种情况,即使定义本身inline不是extern inline. 这是设计使然,因此您可以在头文件中有一个内联定义,您可以通过为外部声明添加一行来将其包含到提供外部定义的源文件中。

回答by Niloy Rashid

This is because of the way GCC handle inline function. GCC performs inline substitution as the part of optimization.

这是因为 GCC 处理内联函数的方式。GCC 执行内联替换作为优化的一部分

To remove this error use staticbefore inline. statickeyword force the compiler using static keyword forces the compiler to take this inline function which make the program compiles successfully.

static在内联之前使用此错误,请使用。static关键字 force 编译器使用 static 关键字强制编译器采用此内联函数,从而使程序编译成功。

static inline int func(int i) {
 return i+1;
}
...
i = func(i);