Inline functions in C#?

It is indeed inlined - but any inline request can be ignored by the compiler.


It is necessarily treated by the compiler as a request for inline -- which it can ignore. There are some idioms for defining some functions in the header (e.g. empty virtual destructors) and some necessary header definitions (template functions), but other than that see GotW #33 for more information.

Some have noted that the compiler may even inline functions you never asked it to, but I'm not sure whether that would defeat the purpose of requesting to inline a function.


Yes, functions that are defined inside a class body are implicitly inline.

(As with other functions declared inline it doesn't mean that the complier has to perform inline expansion in places where the function is called, it just enables the permitted relaxations of the "one definition rule", combined with the requirement that a definition must be included in all translation units where the function is used.)


As stated by others, a method defined within a class is automatically requested inline. It's useful to understand why.

Suppose it weren't. You'd have to generate code for such a function, and everywhere it is called, a jump to subroutine instruction would have to reference the location, via the linker.

class A {
public:
  void f() { ... your code ... }
};

Every time this code is seen, if it's not inline, the compiler can only assume it must be generated, so it would generate a symbol. Suppose it was like this:

A__f_v:

If that symbol were global, then if you happened to include this class code multiple times in different modules, you would have a multiply defined symbol error at link time. So it can't be global. Instead, it's file local.

Imagine you include the above header file in a number of modules. In each one, it's going to generate a local copy of that code. Which is better than not compiling at all, but you're getting multiple copies of the code when you really need only one.

This leads the the following conclusion: if your compiler is not going to inline a function, you are significantly better off declaring it somewhere once, and not requesting it to be inlined.

Unfortunately, what is and is not inline is not portable. It's defined by the compiler writer. A good rule of thumb is to always make every one liner, particularly all functions which themselves just call a function, inline, as you remove overhead. Anything below three lines of linear code is almost certainly ok. But if you have a loop in the code, the question is whether the compiler will allow it inline, and more to the point, how much benefit you would see even if it did what you want.

consider this inline code:

inline int add(int a, int b) { return a + b; }

It's not only almost as small as the prototype would be in source code, but the assembly language generated by the inline code is smaller than the call to a routine would be. So this code is smaller, and faster.

And, if you happen to be passing in constants:

int c= add(5,4);

It's resolved at compile time and there is no code.

In gcc, I recently noticed that even if I don't inline code, if it's local to a file, they will sneakily inline it anyway. It's only if I declare the function in a separate source module that they do not optimize away the call.

On the other end of the spectrum, suppose you request inline on a 1000 line piece of code. Even if your compiler is silly enough to go along with it, the only thing you save is the call itself, and the cost is that every time you call it, the compiler must paste all that code in. If you call that code n times, your code grows by the size of the routine * n. So anything bigger than 10 lines is pretty much not worth inlining, except for the special case where it is only called a very small number of times. An example of that might be in a private method called by only 2 others.

If you request to inline a method containing a loop, it only makes sense if it often executes a small number of times. But consider a loop which iterates one million times. Even if the code is inlined, the percentage of time spent in the call is tiny. So if you have methods with loops in it, which tend to be bigger anyway, those are worth removing from the header file because they a) will tend to be rejected as inline by the compiler and b) even if they were inlined, are generally not going to provide any benefit