GOTW # 27 turn function (Forwarding functions)
Difficulty: 3/10
How do I write the moving call function? The original answer is very simple, but we already know that the C language has recently changed.
problem
The turn function is useful for transmitting tasks to other functions or objects, especially when they are designed.
Comment on the following turn function. Do you try to modify it? If so, how come?
// file f.cpp
#include "f.h"
/*...
BOOL F (X) {
Return G (X);
}
(Note: One of the purposes of this GOTW is to clarify the consequences of subtle improvements in July [1997] to the C language in London.)
answer
The turn function is useful for transmitting tasks to other functions or objects, especially when they are designed.
The key points are: efficiency.
Comment on the following turn function. Do you try to modify it? If so, how come?
// file f.cpp
#include "f.h"
/*...
BOOL F (X) {
Return G (X);
}
Two main improvements can make this function more efficient. The first should always be adopted, the second needs to trade.
1. Reference value using the pass Const in the transmission
"Is this not confusing?" You may ask. No, it will not, at least in this case. Until recently, the C language specifies: because the compiler ensures that the parameter X is not used in other places in addition to being passed, the compiler can be fully optimized. For example, this code:
X my_x;
f (my_x);
Compiler:
a) Generate a MY_X copy supply f () use (which is the shape X X) in the code body of F (), and then passes this copy to g (); or
b) Passing MY_X directly to G () without generating a copy, because it noted that this additional copy is not used in addition to the parameters of g ().
The latter is more efficient, isn't it? This is an optimization of the compiler attempt, isn't it?
Yes, yes, but only the London meeting of July 1997. At that meeting, the "Limiting Compiler as an Optimization of this Cancellation of the additional copy" has been supported. 〖Note 1〗 The only place where the compiler can cancel the extra copy construct is "return value optimization" (in your C Collection query details) and "Temporary objects".
This means that the compiler is required to generate two copies. Since we (as the author of F) know this extra copy is not necessary, we should declare the X & Type parameters in accordance with the usual way.
(Note: If we have been doing this, not, depending on what the compiler is allowed to do, then the change of this rule will not have any effect on us. This is a "simple is beautiful" example - all It may be avoided in the sub-branches of the language, don't play smart.)
2. Function Inline
This needs to be weighed. To be, the default will be implemented as an outreach, and selectively need to be inline to improve the function of efficiency.
When you connect the function, the active face is that you avoid the additional overhead of the call to the F function.
The negative surface is the implementation of the inline F exposes F, and allows the user's code depending on this implementation. When F is changed, all user code must be recompiled. More serious, user code now needs to know the prototype of the function g (), which is a bit disgusting because the user does not call the function G at all, which can not be aware of its prototype at all (at least, from our example, Is such that). Thus, if g () has changed, when accepted other types of other parameters, the user's code will also be able to know the statement of these types. Inline and non-inline can be. We must perform tradeoff between advantages and disadvantages, depending on how F is used, and the extensive extension of use, and the extensive use of how to use it in the future.
The code specification given by GOTW:
l When you pass a parametric, use the reference to the reference to replace the value.
l Avoid function inline, unless PROFILER tells you that there is this necessary (programmer is very irrational in guessing the performance bottleneck)
Note 1: This improvement is necessary, which avoids problems when the compiler is not allowed to omit a copy of the configuration, especially when the copy constructs have side effects. Many times, the code needs to calculate the number of copies of the object.