Inlining Proposal, Revision 1 WG14/N709 (J11/97-072) Bill Homer Tom MacDonald Cray Research, Inc. 655F Lone Oak Drive Eagan, MN 55121 homer@cray.com tam@cray.com 30 May 1997 Note: Revision 1 differs from N700 (J11/97-063) only in the Semantics section for 6.5.x. Following an email discussion on the reflector, that section was rewritten to clarify its intent. Introduction This proposal adds the inline keyword to Standard C in such a way that it can be implemented with existing linker tech- nology and also is compatible with C++. This is achieved by requiring that one and only one of the translation units containing the definition of an inline function be specified as the one that provides an external definition for the function. Because that specification consists simply of a declaration that lacks the inline keyword, it will also be accepted by a C++ translator. This proposal does extend the C++ specification in two ways. First, if a function is declared inline in one translation unit, it need not be declared inline in every other transla- tion unit. This allows, for example, a library function that is to be inlined within the library but to be available only through an external definition elsewhere. (The alter- native of using a wrapper function for the external function both requires an additional name and may adversely impact performance, if a translator does not actually do inline substitution.) Second, the requirement that all definitions of an inline function be ``exactly the same'' is replaced by the require- ment that the behavior of the program should not depend on whether a call is implemented with a visible inline defini- tion or the external definition of a function. This allows an inline definition to be specialized for its use within a particular translation unit. For example, the external definition of a library function might include some argument validation that is not needed for calls made from other functions in the same library. These extensions do offer some advantages, and programmers who are concerned about compatibility can simply abide by the stricter C++ rules. Nevertheless, the extensions are not central to the proposal and the C++ rules could easily be substituted. Edits to draft C9X Draft 10 6.1.1.1 Keywords In the Syntax section, add to the list of keywords: inline 6.5 Declarations In the Syntax section, append to the list of alternatives for the definition of declaration-specifiers: function-specifiers 6.5.x Function-specifiers (a new subsection, intended to follow 6.5.3) Syntax function-specifier: inline Constraints Function-specifiers shall be used only in function declarations. The inline function specifier shall appear only in a file scope function declaration. It shall not appear in a declaration of main. Semantics A function declaration with an inline function specif- ier declares an inline function. The inline function specifier does not affect the meaning of a program. It simply indicates that a translator should attempt to improve the performance of calls to the function (by, for example, using an alternative to the usual function call mechanism known as ``inline substitution''). Any function with internal linkage can be an inline function. For a function with external linkage, the following restrictions apply. If a function is declared with an inline function specifier, then it shall also be defined in the same translation unit. If all of the file scope declarations for a function in a translation unit include the inline function specifier, then the definition in that translation unit is an inline definition. An inline definition does not pro- vide an external definition of the function, and does not hide an external definition in another translation unit. An inline definition provides an alternative to an external definition, which a translator may use to implement any call to the function in the same transla- tion unit. The behavior of the program is undefined if it depends upon whether the inline definition or the external definition is used. (Footnote: Examples of operations in an inline function with external linkage that can lead to undefined behavior include modifying an object declared with the static storage class, or any operation that is present in one but not another definition of the function.) Example The declaration of an inline function can result in either an external definition, or a definition avail- able for use only within the translation unit. A file scope declaration without inline creates an external definition. The following example shows an entire translation unit. inline double fahr(double t) { return (9.0 * t) / 5.0 + 32.0; } extern double fahr(double); /* creates an external definition */ inline double cels(double t) { return (5.0 * (t - 32.0)) / 9.0; } double convert(int is_fahr, double temperature) { /* A translator may perform inline substitutions. */ return is_fahr ? cels(temperature) : fahr(temperature); } Note that the declarations of inline function fahr result in the creation of an external definition, but the declaration of cels requires an external definition in another translation unit.