简体   繁体   English

C++ 从另一个 cpp 文件调用内联函数

[英]C++ call inline function from another cpp file

I'm trying to understand a few basics about extern, static, etc. and tried the following example, but I don't get why I can't call the function "just" because it's (possibly) inlined.我试图了解有关外部、静态等的一些基础知识,并尝试了以下示例,但我不明白为什么我不能“仅仅”调用该函数,因为它(可能)是内联的。

My first file : F1.cpp我的第一个文件:F1.cpp

 #include <iostream>
 
 void Modify();
 int i;

 int main() {
      i = 1;

      std::cout << "i = " << i << std::endl;
      Modify();
      std::cout << "i = " << i << std::endl;
 
      return 0;
 }

The second file : F2.cpp第二个文件:F2.cpp

#include <iostream>

extern int i;

inline void Modify() {
    i = 99;

    std::cout << "i = " << i << std::endl;

}

With inline keyword in F2.cpp, I get : undefined reference to Modify() in my F1.cpp file.使用 F2.cpp 中的 inline 关键字,我得到:在我的 F1.cpp 文件中对 Modify() 的未定义引用。 Removing it, the code compiles and works fine.删除它,代码编译并正常工作。

I assume that the inline keyword in C++ has some sort of behaviour like the static keyword ?我假设 C++ 中的 inline 关键字具有某种类似于 static 关键字的行为?

I had a look at this topic aswell, but apart from the fact that the documentation says that an inline function should always be in the header file, I don't get it : C++ inline member function in .cpp file我也看过这个主题,但除了文档说内联函数应该始终在头文件中这一事实之外,我不明白: .cpp 文件中的 C++ 内联成员函数

Thanks for your help !谢谢你的帮助 !

I assume that the inline keyword in C++ has some sort of behaviour like the static keyword ?我假设 C++ 中的inline关键字具有某种类似于static关键字的行为?

Similar, but different.相似,但不同。 The name still has external linkage, and the program behaves as if there's only one definition (for example, the function has the same address everywhere, and only one instance of any static variables).该名称仍然具有外部链接,并且程序的行为就像只有一个定义(例如,该函数在任何地方都具有相同的地址,并且任何静态变量只有一个实例)。 The effects of inline are: inline的效果是:

  • The function can be defined in more than one translation unit, as long as all the definitions are identical.只要所有定义都相同,就可以在多个翻译单元中定义该函数。 Regular functions can only be defined once.常规函数只能定义一次。
  • The function must be defined in any translation unit that uses it.该函数必须在使用它的任何翻译单元中定义。 This allows the compiler to omit a non-inline definition if it doesn't need one.这允许编译器在不需要时省略非内联定义。

Your code breaks the second rule, which might or might not lead to a link error.您的代码违反了第二条规则,这可能会也可能不会导致链接错误。 This is why inline functions usually need to be in headers, if you need to use them in more than one unit.这就是为什么内联函数通常需要在标题中,如果您需要在多个单元中使用它们。

According to the C++ Standard (7.1.2 Function specifiers)根据 C++ 标准(7.1.2 函数说明符)

4....If a function with external linkage is declared inline in one translation unit, it shall be declared inline in all translation units in which it appears; 4....如果一个带有外部链接的函数在一个翻译单元中被声明为内联,则它应该在它出现的所有翻译单元中被声明为内联; no diagnostic is required.不需要诊断。

and

4 An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly the same definition in every case 4 内联函数应在每个使用 odr 的翻译单元中定义,并且在每种情况下都应具有完全相同的定义

In C ( section 6.7.4 Function specifiers of the C Standard ) function specifier inline for external functions has different semantic在 C(C 标准的第 6.7.4 节函数说明符)中,外部函数的inline函数说明符具有不同的语义

7....An inline definition does not provide an external definition for the function, and does not forbid an external definition in another translation unit. 7..内联定义不提供函数的外部定义,也不禁止在另一个翻译单元中的外部定义。 An inline definition provides an alternative to an external definition, which a translator may use to implement any call to the function in the same translation unit.内联定义提供了外部定义的替代方案,翻译器可以使用它来实现对同一翻译单元中的函数的任何调用。 It is unspecified whether a call to the function uses the inline definition or the external definition未指定对函数的调用是使用内联定义还是外部定义

Yes, inline has a meaning that's fairly similar to static .是的, inline的含义与static非常相似。 The specific requirement from the standard (§[basic.def.odr]/3) is:标准 (§[basic.def.odr]/3) 的具体要求是:

An inline function shall be defined in every translation unit in which it is odr-used.内联函数应在每个使用 odr 的翻译单元中定义。

In this case, you've defined the inline function in one translation unit, but only declared it in the other, so you're not meeting the requirement above that it be defined in the TU where it's used.在这种情况下,您已经在一个翻译单元中定义inline函数,但仅在另一个翻译单元中声明了它,因此您不满足在使用它的 TU 中定义它的上述要求。

An inline function can still have external linkage.内联函数仍然可以具有外部链接。 When you do this, the standard guarantees that it results in a single function that will have the same address throughout the program.当你这样做时,标准保证它会产生一个在整个程序中具有相同地址的函数。

Just in case it wasn't clear: a translation unit is basically a source file, after preprocessing, so it includes everything directly in that source file plus everything in the headers it includes, minus anything skipped over due to things like #ifdef , #if , etc.以防万一不清楚:翻译单元基本上是一个源文件,经过预处理,因此它直接包含该源文件中的所有内容以及它包含的标题中的所有内容,减去由于#ifdef#if类的内容而跳过的任何内容#if ,等等。

When you declare a function inline , only the translation unit that it is defined in (in this case, F2.cpp) has access to this function.当您声明一个函数inline ,只有定义它的翻译单元(在本例中为 F2.cpp)才能访问该函数。 If you instead put it in a header file (say Fh), and #include "Fh" in both F1.cpp and F2.cpp, then the inline function is defined twice, once in each translation unit.如果您改为将其放在头文件(例如 Fh)中,并在 F1.cpp 和 F2.cpp 中#include "Fh" ,则inline函数定义两次,每个翻译单元一次。 Normally, this would cause a linker error, but since you declared the function inline , the linker doesn't know about your Modify() function.通常,这会导致链接器错误,但由于您声明了函数inline ,链接器不知道您的Modify()函数。

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

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