Why doesn't C# have an 'inline' keyword?

I got this question in email today, and I thought I'd share my response.

For those of you who don't know, the 'inline' keyword in the C language was designed to control whether the compiler inlined a function into the calling function. For example, if I had something like

int square(int x)
{
    return x * x;
}

and used it here:

int y = square(x);

I would be making a function call for a single expression, which would be pretty inefficient. Adding “inline' to the definition would tell the compiler to inline it, effectively changing my use to:

int y = x * x;

and giving me the abstract of a function call without the overhead.

Inline had some good uses in early C compilers, but it was also prone to misuse - some programmers would decorate all their functions with 'inline', which would give them no function calls, very big code, and therefore slow execution.

That led to the next phase, where programmers would only put 'inline' on functions where they needed the performance. That kept the code smaller, but missed cases like the one I have above where the inlined code is smaller than the function call code, where you want to inline every time. These cases only got caught if the programmer noticed them.

Finally, as systems got better, compilers got into the act, and started doing enough analysis to make good decisions on their own without 'inline' keyword. In fact, the compiler writers discovered that the heuristics that they put in the compiler made better choices than programmers did, and some compilers started ignoring 'inline' and just doing what they thought best. This was legal because inline was always defined as a hint, not a requirement.

This worked really well for most cases, but there were some cases where the programmer really wanted something to be inline (ie override the heuristics). This was sometimes around as a request for the “inlinedammit!“ keyword, which showed up in VC++ in V6.0 (IIRC) as the nicer named “__forceinline“.

So how does that relate to C#? Well, it doesn't, but it's an interesting story so I wanted to share it with you.

For C#, inlining happens at the JIT level, and the JIT generally makes a decent decision. Rather than provide the ability to override that, I think the real long-term solution is to use profile-guided feedback so that the JIT can be smarter about what it inlines and what it doesn't.