简体   繁体   中英

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

 #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

#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. 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 ?

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

Thanks for your help !

I assume that the inline keyword in C++ has some sort of behaviour like the static keyword ?

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:

  • 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)

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

In C ( section 6.7.4 Function specifiers of the C Standard ) function specifier inline for external functions has different semantic

7....An inline definition does not provide an external definition for the function, and does not forbid an external definition in another translation unit. 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 . The specific requirement from the standard (§[basic.def.odr]/3) is:

An inline function shall be defined in every translation unit in which it is odr-used.

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.

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.

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. 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. Normally, this would cause a linker error, but since you declared the function inline , the linker doesn't know about your Modify() function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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