4

This should be easy points for those who answer. There is a logical answer to this question, but I wanted to ask just to verify.

My understanding of how program flow works is simple. A function and its associated instructions are located at some point in memory. This location in memory is the single location that is used to store such instructions. When called, the location of the first instruction of that function is stored in the program flow. This memory pointer instructs the CPU where to go in memory to find the instructions for the required function. After jumping to this location and executing the instructions, normal program flow is restored and the CPU jumps back to where the original address instruction was located to proceed with successive instructions.

It is my understanding that inline functions are pasted right into the locations in which they were called. So, when a source file is written and an inline function defined, there actually exist multiple locations in memory where this function's instruction set is located (namely exactly where it is called). So, that is to say there is not an source location in memory similar to that of a non-inline function?

Further, during the compiling process, does the compiler just paste the inline function exactly where it was called and remove/replace the arbitrary argument names of the function's definition with the parameters passed to it?

5 Answers 5

4

It is my understanding that inline functions are pasted right into the locations in which they were called.

It depends. Even though a function is inline it may not actually be inlined by the compiler.

So, that is to say there is not an source location in memory similar to that of a non-inline function?

It depends how the function was inlined. If there were 4 calls to an inline function in a translation unit, the compiler might decide that inlining one of them is OK, and the remaining calls should use a regular function call. So in this case there's a "source" location and an inlined location.

Further, during the compiling process, does the compiler just paste the inline function exactly where it was called and remove/replace the arbitrary argument names of the function's definition with the parameters passed to it?

An inlined function must have the same meaning as a normal function call.

Sign up to request clarification or add additional context in comments.

5 Comments

What are the factors considered for this decision? I had a basic implementation of an inline function on an MCU and the programs word size changed depending on whether I had implemented inline or not.
@sherrellbc, it's basically up to the compiler to make this determination, as with all optimizations. All inline does is provide a hint that the call should be as fast as possible.
Similar to the the register modifier it seems. Thanks.
In the sense that it's a hint to the compiler, yes, it's similar to register. Compilers that support inlining usually have a (non-portable) option or extension to "really" or "always" inline a function.
Even if every call is inlined, the compiler still has to generate a function if its address is taken. And inline is similar to register in that compilers can ignore it, but practically they are quite different because modern compilers ignore register altogether (except that you can't take the address of one).
3

It is almost as you are thinking. First of all - it depends on the language / compiler. In C and GCC or MSVCC if you tell that function is an "inline" function it does not mean it will be inlined! This depends on the compiler and its implemenetation and your inline keyword / pragma is only a hint.

Additional if function is marked as "inline" than it is pasted everywhere original calls were but ... it is not deleted if you are compiling a library (static or dynamic). But if compiler decides to inline it, it really pastes the code ant optimizes the call.

Btw. in Haskell (GHC) the "inline" pragma is not only a hint, but you can be sure, compiler will do the inline process. Personally I would love to have a C++ compiler which will really inline every function I tell him to :)

2 Comments

Would it be in the case of the compilation of a dynamic library that the function definition is not deleted because other programs sharing the library would require it as well? It seems obvious but I do not know much about DLLs so I just wanted to make sure.
@sherrellbc: Exaclty. Of course if the function is accessible outside of such library (and not private or protected).
2

My understanding matches yours. Inline compilation removes the function and replaces it inline with the commands within that function. Any arguments are replaced inline with the values passed to them. As you said - no jump in execution, no function added to the call stack.

Comments

2

Compiler is free to choose whether the function declared inline should be in-lined or not. When in-lined, there will be benefits such as,

  • Execution will be fast. (Since no jump instructions which will flush the CUP cache)
  • Memory usage
    • Code memory: If you are in-lining a function which is used in many places, then the code size will increase.
    • Stack usage: If your in-lined function uses more variables, then more stack space is used.

Edit: When to use in-line

  1. Use inline function instead of #define. (Macro expansion are done during per-processing time. where the compiler is not at all in the picture. But for inline functions, compiler is in picture and it can do error checking...)
  2. Use inline function if the function is very small.
  3. Use inline function if the function is often used in many places.

3 Comments

Not sure that I agree on the second bullet point - because of all the copied code, the instruction set will be bigger. So you'll need (potentially much) more memory to hold the instruction set, while the memory needed for one extra stack frame (especially of an inlinable func) is not that high.
For #1 of your list, are you referring to any function-like macro? For example, if you had a macro that returned the min of two numbers?
@sherrellbc: Yes... Macro expansion are done during per-processing time. where the compiler is not at all in the picture. But for inline functions, compiler is in picture and it can do error checking, etc...
1

Page 112 of ISO/IEC 9899:TC2 at open-std.org tells us:

A function declared with an inline function specifier is an inline function ... Making a function an inline function suggests that calls to the function be as fast as possible.(118) The extent to which such suggestions are effective is implementation-defined.(119)

The footnotes of that section tell us:

(118) By using, for example, an alternative to the usual function call mechanism, such as ‘‘inline substitution’’. Inline substitution is not textual substitution, nor does it create a new function. Therefore, for example, the expansion of a macro used within the body of the function uses the definition it had at the point the function body appears, and not where the function is called; and identifiers refer to the declarations in scope where the body occurs. Likewise, the function has a single address, regardless of the number of inline definitions that occur in addition to the external definition.

(119) For example, an implementation might never perform inline substitution, or might only perform inline substitutions to calls in the scope of an inline declaration.

I added boldface to the parts I think address or correct your understanding of inline.

I would suggest consulting your compiler implementation notes if you want to force or hope for a specific behaviour of inline. The small points about (non) textual substitution and single address are interesting.

2 Comments

This is a bit confusing as I am not completely literate in this space. What is meant by textual substituion? From this paragraph I gather that the expansion of a macro inside a function that calls it uses the definition available to the compiler when entering the calling function (i.e. if a new macro definition is written within that function it will not be implemented for the macro call within the same scope). What is meant by the inline function having only a single address and the possibility of several definitions. I thought that a function may have a single definition.
Regarding "textual substitution"... Rather than declare a function inline, one could simply copy and paste the body of the function definition into the code where it was to be called, renaming its parameters to variables already in scope. This would be faster to "call" and take up more code space, for sure. It would also be exposed to changes in macro expansions within that function if macro definitions changed between when the compiler parsed the original function definition and when it parsed the newly pasted inline code. What I describe is textual substitution.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.