The only way to determine this is to examine it in the context and look at generated assembly.
In many cases, the resulting code is surprisingly convoluted and has nothing in common with source code - yet is functionally identical.
As a general recommendation:
- pass basic types by value
- pass everything else by const reference
But now consider the modern optimizing compilers:
struct Message { int x, float y, std::string s, Vector3 pos };void foo( const Message & msg ){ std::cout << msg.x;}...void bar(){ Message myMessage; myMessage.x = 10; myMessage.y = 3.14; myMessage.s = "Hello World"; myMessage.pos = ....; foo(myMessage)}
Optimizing compilers will change the above code into:
void bar(){ std::cout << 10; /y, s, pos do not even get initialized, since they have no side-effects}
Conclusion:
Unless you need to maintain some external API for linking/compatibility purposes, or are using virtual calls, fuctions get too mutilated to make any reasonable conclusion.