Why are C ++ built-in functions in the header?

NB This is not a question of how to use the built-in functions or how they work, but of why they are made as they are.

A declaration of a member function of a class should not define the function as inline , it is only the actual implementation of the function. For example, in the header file:

 struct foo{ void bar(); // no need to define this as inline } 

So why should the built-in implementation of the class function be in the header file? Why can't I insert an inline function into a .cpp file? If I tried to put the inline definition in a .cpp file, I would get an error of the form:

 error LNK2019: unresolved external symbol "public: void __thiscall foo::bar(void)" (?bar@foo@@QAEXXZ) referenced in function _main 1>C:\Users\Me\Documents\Visual Studio 2012\Projects\inline\Debug\inline.exe : fatal error LNK1120: 1 unresolved externals 
+106
c ++ c ++ - faq language-design theory inline
Feb 20 '11 at 12:28
source share
8 answers

An inline function definition does not have to be in the header file, but because of one definition rule for built-in functions, an identical function definition must exist in every translation unit that uses it.

The easiest way to achieve this is to put the definition in the header file.

If you want to put a function definition in one source file, you should not declare it inline . A function not declared inline does not mean that the compiler cannot inline function.

Whether you should declare an inline function or not, it is usually a choice that you should make based on the version of the definition rules for which you would be best suited; adding inline and then limiting yourself to the following restrictions makes little sense.

+107
Feb 20 '11 at 12:35
source share

There are two ways to look at this:

  1. Inline functions are defined in the header, because for an inline function call, the compiler must be able to see the body of the function. For the naive compiler to do this, the function body must be in the same translation unit as the call. (A modern compiler can optimize the work with translation units, so a function call can be built-in even if the function definition is in a separate translation module, but these optimizations are expensive, the compiler is not always included and not always supported)

  2. the functions defined in the header must be marked inline , because otherwise each translation unit that includes the header will contain a function definition, and the linker will complain about multiple definitions (violation of the unified definition rule). The inline suppresses this by allowing multiple translation units to contain (identical) definitions.

These two explanations really boil down to the fact that the inline not quite what you expect.

The C ++ compiler can apply embedding optimization (replace the function call with the body of the called function, saving the overhead of the call) at any convenient time, unless it changes the observed behavior of the program.

The inline makes it easier for the compiler to apply this optimization by allowing the function definition to be displayed in multiple translation units, but using the keyword does not mean that the compiler must inline the function, and not using the keyword does. Do not forbid the compiler to insert the function.

+102
Feb 20 '11 at 13:01
source share

This is the limit of the C ++ compiler. If you put a function in the header, all the cpp files into which it can be embedded can see the "source" of your function, and embedding can be done by the compiler. Another, as the attachment must be done by the linker (each cpp file is compiled separately in the obj file). The problem is that in the linker it would be much harder to do this. A similar problem exists with the "templates" of classes / functions. They need to create an instance by the compiler, because the linker will have the problem of creating an instance (creating a specialized version). Some new compilers / linkers can compile / link "two passes" when the compiler performs the first pass, and then the linker does its work and calls the compiler to solve unresolved things (inline / templates ...)

+20
Feb 20 '11 at 12:30
source share

The reason is that the compiler must really see the definition in order to be able to drop it instead of calling it.

Remember that C and C ++ use a very simplified compilation model, where the compiler always sees only one translation unit at a time. (This fails for export, which is the main reason why only one vendor actually implemented it.)

+9
Feb 20 '11 at 12:35
source share

The C ++ inline is misleading, it does not mean "embed this function." If a function is defined as being built-in, it simply means that it can be defined several times as long as all definitions are equal. It is perfectly legal for a function marked inline to be a real function that is called instead of entering the code in the place where it was called.

Defining a function in the header file is necessary for templates, since, for example, a template class is not really a class, it is a template for a class, which you can do in several ways. In order for the compiler to, for example, create the function Foo<int>::bar() , when you use the Foo template to create the Foo class, the actual definition of Foo<T>::bar() must be visible.

+8
Feb 20 '11 at 12:35
source share

I know this is an old thread, but I thought I should specify the extern keyword. I recently ran into this problem and solved as follows

helper.h

 namespace DX { extern inline void ThrowIfFailed(HRESULT hr); } 

Helper.cpp

 namespace DX { inline void ThrowIfFailed(HRESULT hr) { if (FAILED(hr)) { std::stringstream ss; ss << "#" << hr; throw std::exception(ss.str().c_str()); } } } 
+3
May 2 '14 at 15:46
source share

Because the compiler must see them for inline ones . And header files are “components” that are usually included in other translation units.

 #include "file.h" // Ok, now me (the compiler) can see the definition of that inline function. // So I'm able to replace calls for the actual implementation. 
+2
Feb 20 '11 at 12:29
source share

Built-in functions

In C ++, a macro is nothing more than a built-in function. So now macros are under compiler control.

  • Important : if we define a function inside a class, it will automatically become Inline

The Code Inline function is replaced where it is called, so this reduces the overhead of calling the function.

In some cases, the insert function may not work, for example,

  • If a static variable is used inside an inline function.

  • If the function is complicated.

  • If a recursive function call

  • If the address of the function is taken implicitly or explicitly

A function defined outside the class, as shown below, may become inline

 inline int AddTwoVar(int x,int y); //This may not become inline inline int AddTwoVar(int x,int y) { return x + y; } // This becomes inline 

A function defined inside a class also becomes inline

 // Inline SpeedMeter functions class SpeedMeter { int speed; public: int getSpeed() const { return speed; } void setSpeed(int varSpeed) { speed = varSpeed; } }; int main() { SpeedMeter objSM; objSM.setSpeed(80); int speedValue = A.getSpeed(); } 

Here the getSpeed ​​and setSpeed ​​functions will become inline

+1
Aug 10 '18 at 12:13
source share



All Articles