TITLE: virtuals and inlining (Newsgroups: comp.lang.c++.moderated, 28 Mar 97) SHU: shu@scott.net |> `inline' is a request to the compiler. the compiler may or may not |> satisfy this request. clearly, good compilers will try to satisfy it |> more often than not. (btw: can anyone tell me at least one good reason |> for making `inline' part of the language proper as opposed to pragma, |> for example?) KANZE: James Kanze Because the keyword inline affects the syntax of the program. Normally, a function must be defined once, and only once, in the entire program. Multiple definitions are an error. If a function is defined inside a class definition, or if a definition or a declaration of the function have the keyword "inline", however, then it is legal to define the once in each translation unit; in fact, it is required that the function be defined in any translation unit in which it is used. >From a standards point of view, this is the *entire* meaning of "inline". Whether the compiler actually generates the code inline or not is up to the compiler, whether the function is declared inline or not. A really perverse implementation could make a point of inlining all functions except those declared inline, and still be conforming. In practice, of course, seeing the definition (and not just the declaration) is a necessary condition for most compilers to inline. Without the keyword inline, it is illegal for you to make the definition available in more than one compilation unit; with the keyword inline, you are required to make it available in all units. So in practice, the compiler will probably not be able to inline functions that are not declared inline. SHU: |> you are perfeclt write `virtual' and `inline' are sort of |> contradictory. KANZE: Not at all. The two concepts are completely orthogonal. SHU: |> yes, function body is *likely* generated. in fact i do |> not know of any other technique to ensure virtuality though there |> might be something else. KANZE: In practice, the function body will be generated, although probably only in one compilation unit; the one in which the vtbl is generated. (One frequent practice is to use the compilation unit in which the first non-inline virtual function is defined.) SHU: |> yes, it is very likely that each file (ok, |> `translation unit') contains a body for the function as inline |> functions have static linkage, i.e. generating body in this.C will not |> make a body available in other.C. KANZE: This is not true. It was never true for member functions. (A member function cannot have static linkage, period, and never could.) It is no longer true for global functions, unless you explicitly declare them static. In practice, earlier C++ compilers did not always strictly conform to this, and many made even inline member functions static. For this reason, for example, a number of coding guidelines prohibit making any function whose address is taken, or any function using local static variables, inline. This is a work-around for compiler "bugs", however, and not what the language requires. A certain number of modern compilers (most?) use compile time template instantiation. All of them have mechanisms to avoid multiple copies of instantiated templates. I would expect that in time, they will all use this method to avoid multiple copies of out-of-lined inline functions as well. As an example of such methods: Sun CC generates template instantiations in a repertory. If the function is already there, it doesn't regenerate it. PC compilers generate instances in a special segment, which gets overlaid by the linker. Both, I think, get screwed up if the definition is different in different compilation units. But that is undefined behavior, according to the standard. So they have a legal right to get screwed up. (Whether they have a moral right is another question. I scrupulously avoid the problem, because earlier compilers did get screwed up. A change in a single line of a template, and the repository gets deleted and everything recompiled.) SHU: |> there is also another side of the issue -- a compiler does not *have* |> to generate vurtual function calls through pointers. all it *has* to |> do is to make sure the correct version of a virtual function is |> called. if the call is made trough pointer/reference then the only |> (practically known?) way to go is via pointer. however if a function |> is called via object then the compiler may expand an inline as it |> knows at compile time what the object will be at run time. KANZE: Every compiler I've seen actually does this. SHU: |> in fact |> this is the only good reason i can see to have a function both |> `inline' and `virtual' -- to tell the compiler: "please inline the |> function wherever possible and generate normal virtual call wherever |> you have to.".