How Will I Know Whether Inline Function Is Actually Replaced at the Place Where It Is Called or Not

How will i know whether inline function is actually replaced at the place where it is called or not?

Programatically at run-time, You cannot.

And the truth of the matter is: You don't need to know

An compiler can choose to inline functions that are not marked inline or ignore functions marked explicitly inline, it is completely the wish(read wisdom) of the compiler & You should trust the compiler do its job judiciously. Most of the mainstream compilers will do their job nicely.

If your question is purely from a academic point of view then there are a couple of options available:



Analyze generated Assembly Code:

You can check the assembly code to check if the function code is inlined at point of calling.

How to generate the assembly code?

For gcc:

Use the -S switch while compilation.

For ex:

g++ -S FileName.cpp

The generated assembly code is created as file FileName.s.

For MSVC:

Use the /FA Switch from command line.

In the generated assembly code lookup if there is a call assembly instruction for the particular function.



Use Compiler specific Warnings and Diagnostics:

Some compilers will emit a warning if they fail to comply an inline function request.

For example, in gcc, the -Winline command option will emit a warning if the compiler does not inline a function that was declared inline.

Check the GCC documentation for more detail:

-Winline

Warn if a function that is declared as inline cannot be inlined. Even with this option, the compiler does not warn about failures to inline functions declared in system headers.

The compiler uses a variety of heuristics to determine whether or not to inline a function. For example, the compiler takes into account the size of the function being inlined and the amount of inlining that has already been done in the current function. Therefore, seemingly insignificant changes in the source program can cause the warnings produced by -Winline to appear or disappear.

how Inline function code is replaced in calling place?

From the C++ FAQ:

When the compiler inline-expands a function call, the function's code
gets inserted into the caller's code stream (conceptually similar to
what happens with a #define macro). This can, depending on a zillion
other things, improve performance, because the optimizer can
procedurally integrate the called code — optimize the called code into
the caller.

There are several ways to designate that a function is inline, some of
which involve the inline keyword, others do not. No matter how you
designate a function as inline, it is a request that the compiler is
allowed to ignore: it might inline-expand some, all, or none of the
calls to an inline function. (Don't get discouraged if that seems
hopelessly vague. The flexibility of the above is actually a huge
advantage: it lets the compiler treat large functions differently from
small ones, plus it lets the compiler generate code that is easy to
debug if you select the right compiler options.)

In the simplest case, the inline function is dropped into its call site as if you had copy-and-pasted it there. Thus for,

inline int madd( int a, int b, int c ) 
{
return a * b + c;
}

void foo( int data[3] )
{
int result = madd( data[0], data[1], data[2] );
printf("%d\n", result); // note to pedants: this is simpler than a cout stream, so there
}

the compiler could turn it into

void foo( int data[3] )
{
int result = data[0] * data[1] + data[2] ; // madd is replaced inline
printf("%d\n", result);
}

When inline function actually replaces the code and is it possible to put a break point?

1) Simple answer: It does not work with virtual functions most of the time. See Are inline virtual functions really a non-sense? for a more detailed answer.

2) Yes you can. Compilers normally do not perform any inlining for debug builds.

3) Of course the compiler does not put the "ret" assembly instruction in the calling code. Think abut it that way:

// before inlining:
int MyFunc () { return 5; }
int i = MyFunc();

// after inlining:
int i = 5;

4) See here for an answer: How do I force gcc to inline a function?

BTW: Using Google would have answered all your questions in less time ;-)

is Inline code replaced at compile time or run time?

Compile time.
The compiler is actually free to ignore the inline keyword. It is only a hint (except that inline is necessary in order to allow a function to be defined in a header file without generating an error message due to the function being defined in more than one translation unit).

When are functions inlined within the compilation process

I think examining the assembly code is the best (and pretty much the only) way to see what's been inlined.

Bear in mind that, in certain circumstances, some inlining can take place at link time. See Can the linker inline functions?

What the inline function actually do?

Ideally, with the inline keyword, the compiler pastes the contents of the inlined function at the point where the function is called.

Given:

void Print(void)
{
cout << "Hello World!\n";
}

int main(void)
{
Print();
return 0;
}

The compiler would emit an assembly instruction to call the Print function inside the main function.

When declaring the Print function as inline, the compiler would generate the conceptual main() function below:

int main(void)
{
// Substitute content of Print function because it's declared as inline
cout << "Hello World!\n";

return 0;
}

Remember that the inline keyword is a suggestion to the compiler and the compiler can ignore it. The compiler may already inline small functions without using the inline keyword.

Long ago, the inline keyword was used to force compilers to paste code where the function was invoked. This technique was used to eliminate function call overhead. This was in the times when compilers were less intelligent about optimizing.

How can I verify whether a function is expanded as inline by the C++ compiler?

You can enable the -Winline warning which prints a warning when a function marked inline wasn't inlined.

See the documentation.

As an alternative, you can mark the function always_inline which will trigger an error if it wasn't inlined. See the documentation.

What does compiler really do when a class inline function is called?

An optimizing compiler can inline as it wishes.

For example, you might compile and link an entire program with g++ -flto -O2 (link-time whole program optimization option of GCC...).

(caveat: using g++ -flto -O2 would slow down significantly your build process; basically everything is compiled nearly "twice", once at "compile" time, once at "link" time, where GIMPLE representation gets re-optimized)

You'll be surprised by what function calls get inlined (a lot of them could be). It is unrelated to static or not functions marked or not as inline.

So you should not care about inlining (it is an implementation and optimization detail), but you hope that the compiler will do a good job.

(sometimes with g++ you want to disable most inlining to ease debugging with gdb; then compile with g++ -fno-inline -Wall -Wextra -O0 -g)

So these inline functions will not be replaced by compiler when they are called outside the class, am I right?

You are wrong, this is just an implicit argument (see also that), and of course compilers are often inlining calls to member functions. In practice C++ would be inefficient if compilers did not that optimization (since many member functions -e.g. getters and setters- are quite short and quick).

Remember that C++ is a specification written in some report (it is not a compiler). Inlining is a quality of implementation issue, and may or not happen.

If you care about what do the compiler really does (and you should not care, but you need to avoid undefined behavior in your code), ask it to show the generated assembler code. With GCC compile with g++ -O2 -fverbose-asm -S to get a foo.s assembler file from a foo.cc translation unit.



Related Topics



Leave a reply



Submit