I was reading the source code of OS/161 and encountered inline support code. I am not able to understand the comment provided. The comment is :-
/*
* Material for supporting inline functions.
*
* A function marked inline can be handled by the compiler in three
* ways: in addition to possibly inlining into the code for other
* functions, the compiler can (1) generate a file-static out-of-line
* copy of the function, (2) generate a global out-of-line copy of the
* function, or (3) generate no out-of-line copy of the function.
*
* None of these alone is thoroughly satisfactory. Since an inline
* function may or may not be inlined at the compiler's discretion, if
* no out-of-line copy exists the build may fail at link time with
* undefined symbols. Meanwhile, if the compiler is told to generate a
* global out-of-line copy, it will generate one such copy for every
* source file where the inline definition is visible; since inline
* functions tend to appear in header files, this leads to multiply
* defined symbols and build failure. The file-static option isn't
* really an improvement, either: one tends to get compiler warnings
* about inline functions that haven't been used, which for any
* particular source file tends to be at least some of the ones that
* have been defined. Furthermore, this method leads to one
* out-of-line copy of the inline function per source file that uses
* it, which not only wastes space but makes debugging painful.
*/
Please can anyone explain me what do they mean by file-static out-of-line, global out-of-line and no out-of-line copy of the function
The “normal” implementation of a function creates it as a subroutine in the assembly language or machine code generated by the compiler: It is a sequence of instructions that is called by other routines, and it returns when it is complete.
Since calling a function and returning from it may have some overhead, a compiler may instead generate an inline implementation of the function. For example, with this code:
int square(int x) { return x*x; }
...
void foo(...)
{
...
y = square(x);
}
the compiler could choose to compile foo
as if it were:
void foo(...)
{
...
y = x*x;
}
Thus, the compiler embeds the contents of the function inside the routine that called it. This is called an inline implementation.
The comments you quote use out-of-line to refer to the normal implementation of a function as an actual subroutine. It is not a commonly used phrasing, but is not unusual either.