A
Andrey Tarasevich
JKop said:Okay, I'm trying to get my head around this. Consider the following header
file, "yum.hpp":
#ifndef INCLUDE_YUM_HPP
#define INCLUDE_YUM_HPP
inline int Yum(char k)
{
return k - 5;
}
#endif
Now, consider that this function is called... inlinedly... in every instance
that it's called throughout the entire program, like so:
A.cpp
#include "yum.hpp"
int blah(void)
{
return Yum('s');
}
B.cpp
#include "yum.hpp"
int poo(char* n)
{
return Yum(*n);
}
So there's no problem at all with that.
Excellent.
But consider that there's just 3 instances in the program where it's
called... outlinedly. Each of these three callings are from 3 different
source files, 3 different translation units. The "problem" here is that this
fully-fledged function will be in memory not once, twice, but thrice. 3
copies of it in memory - that's a waste. If I were to specify external
linkage (and how would I?) for this function, then the linker would start
complaining because I'd have a multiple definition for each of the
translation units that include my "yum.hpp".
Firstly, at the language level there's no way to detect how many copies
of fully-fledged function body you have in your code (until you start
comparing addresses of this functions in different translation units).
This means that implementation is allowed to keep several copies if it
decides to do so. I don't think it could be referred to as a "waste"
since you yourself declared this function as 'inline', i.e. you yourself
requested the compiler to substitute _a_ _copy_ of function code in
every place where it is called. If you think about it, this is pretty
much the same kind of "waste" as having several copies of fully-fledged
function body.
Secondly, in order to ensure that the function has the same address in
all translation units, the implementation should be able to recognize
the situations where the address of an inline function is taken and
"synchronize" their results between translation units, i.e. all pointers
to inline function should actually point to the same fully-fledged
function body. This is typically ensured by the linker. In the end, only
one copy of fully-fledged function body is really used in the program.
All other copies are not be used and can be safely discarded. This is
also done by the linker.
Thirdly, it is responsibility of the implementation to make sure that
there are no diagnostic messages (from the linker or anywhere else)
triggered by multiple copies of fully-fledged function body. There are
different ways to achieve that and I don't really understand why you
even care about it.
So here's my question: How to you get the function to be inline... yet...
where there's instances where it's called outlinedly, that there's only one
copy of it in memory, as opposed to 3.
In short, you follow these steps:
1. Generate three copies in memory (done by the compiler)
2. Make sure only one copy is actually used by redirecting all
references to a single copy (done by the linker)
3. Discard unused copies (done by the linker)