简体   繁体   English

.c 文件中的 C99 内联函数

[英]C99 inline function in .c file

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'".在链接期间,我得到了“对‘func’的未定义引用”。 Why?为什么?

The inline model in C99 is a bit different than most people think, and in particular different from the one used by C++ C99 中的inline模型与大多数人认为的有点不同,特别是与 C++ 使用的不同

inline is only a hint such that the compiler doesn't complain about doubly defined symbols. inline只是一个提示,以便编译器不会抱怨双重定义的符号。 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 after the inline definition:要强制生成符号,您必须在内inline定义之后添加一种实例化:

int func(int i);

Usually you'd have the inline definition in a header file, that is then included in several .c files (compilation units).通常,您会在头文件中包含inline定义,然后将其包含在多个 .c 文件(编译单元)中。 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.您可能只会看到您遇到的问题,因为您没有对编译器运行进行优化。

So, your use case of having the inline in the .c file doesn't make much sense, better just use static for that, even an additional inline doesn't buy you much.因此,您在 .c 文件中使用inline用例没有多大意义,最好为此使用static ,即使额外的inline也不会给您带来太多好处。

C99 inline semantics are often misunderstood. C99 内联语义经常被误解。 The inline specifier serves two purposes: inline说明符有两个用途:

First, as a compiler hint in case of static inline and extern inline declarations.首先,作为static inlineextern inline声明的编译器提示。 Semantics remain unchanged if you remove the specifier.如果删除说明符,语义将保持不变。

Second, in case of raw inline (ie without static or extern ) to provide an inline definition as an alternative to an external one, which has to be present in a different translation unit.其次,在原始inline (即没有staticextern )的情况下,提供内联定义作为外部定义的替代,外部定义必须存在于不同的翻译单元中。 Not providing the external one is undefined behaviour, which will normally manifest as linking failure.不提供外部是未定义的行为,通常表现为链接失败。

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

This is because of the way GCC handle inline function.这是因为 GCC 处理内联函数的方式。 GCC performs inline substitution as the part of optimization . GCC 执行内联替换作为优化的一部分

To remove this error use static before inline.要消除此错误,请在内联之前使用static Using static keyword force the compiler to inline this function, which makes the program compile successfully.使用static关键字强制编译器内联此函数,从而使程序编译成功。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM