Here’s a tip that makes some confusions for me:”to have the best passing method pass built-in types by value and other types by reference to constant” now I have some questions below:
1-first of all I think the reason behind suggesting passing by reference to constant is that if the referenced object is not volatile the compiler can convert it to pass by value if it would be more efficient but it would have made more sense to me if there was a special syntax by which we could tell the compiler ok here determine the best passing method yourself I don’t care how it will be but changing pass by reference to constant to pass by value by compiler seems messy somehow to me, in the way it is now if we want the compiler to obey the pass by reference to constant and use a pointer we have to force it to do so since it may determine the more efficient way is to pass by value; so can you lighten me up why it is this way that this is?.
2-Does “pass built-in types by value” include built-in types that are bigger in size than size of a pointer like long double on my platform that has 8 bytes comparing to pointer size that is 4 bytes and does “pass non-built-in types by reference to constant” include things like below that likely can be transfered in memory like built-in types:
struct Test1{
public:
char characters[2];
};
struct Test2{
public:
char characters[4];
};
Boost provides this, as
boost::call_traits<T>::param_type.Probably because the rule of thumb works most of the time. If in doubt, you can pass by const reference and it’s unlikely to be horribly inefficient.
In fact there’s more to the general tip than you say – “small” types which aren’t built-in are also usually best passed by value. For example, the standard library consistently passes iterators by value.
Yes. You can reasonably expect a C++ implementation to pass a
doubleorlong doubleby value with acceptable efficiency for almost all practical purposes. If you’ve reached the stage of optimization where this is the lowest-hanging fruit, then you’re beyond general tips. You would measure both in your actual program.Maybe. If the call is successfully inlined, then the compiler can do pretty much anything. If the call target isn’t available to the compiler, then it can’t do it, because in practice a change between value vs. const reference parameter requires changes to both the caller and the callee code. Furthermore, aliasing means that unless the compiler has a lot of information about what’s going on, then even with a non-volatile object it can’t necessarily assume that it won’t change:
Unless it’s inlined, this code cannot be changed to pass
aby value, because someone might call it like this:which must print “2”, whereas with
apassed by value it would print “1”.