For anything larger than a 64 bit integer, why would I want to pass by value?
[Update] The question was closed, because it was not specific enough. One comment suggested that I specify a language. I deliberately did not do that, thinking that this site should be language agnostic.
I was prompted to ask this when I was linting some C++ 14 code this morning and was warned that a parameter was being passed by value.
C++ is syntactically interesting because the reference operator sort of blurs the difference between pass by value and pass by reference.
In C, if my function prototype is void foo(hugeStruct x)
then I am passing a huge structure by value and one can be aware of the passing mechanism by looking at the the calling code. If I want pass by reference, the function signature changes to void foo(hugeStruct* x)
and the call changes from foo(myHugeStruct)
to foo(&myHugeStruct)
.
In C++, the protoypes are void foo(hugeStruct x)
and void foo(hugeStruct& x)
but you can't determine the the passing mechanism by looking at the the calling code, which, in both cases, is foo(myHugeStruct)
.
In the case that I found this morning, the calling code was - inadvertently - passing a 256k array, by value. To answer @JMekker's comment
This isn't the 90's, passing parameters to functions has basically zero performance impact.
If that 256k array were passed by value then all 256k of it would be pushed on to the stack (as opposed to pushing only its address when passing by reference) which well cause a stack overflow, especially in the embedded world.
So, please correct any mistakes that I made, and tell me if there is ever a legitimate reason for me to want to pass large data structures by value.
-
4This is hard to answer without a more specific context, but the general answer to this general question is: because passing references to mutable objects can lead can cause multiple outstanding references to the same mutable object (aliasing) causes shared mutable state, which is undesirable because understanding how a function works now requires non-local reasoning. Whereas when passing values to functions by value, they're copied. You can pass your value without fear that the function will do something to tamper with your value, so you don't need to do manual defensive copying yourself.Alexander– Alexander2022年05月25日 14:55:14 +00:00Commented May 25, 2022 at 14:55
-
1This question could be improved if you added the language. Different languages have wildly different strategies of dealing with pass-by-value versus pass-by-reference models, and the underlying implementation (passing a pointer versus copying memory bytes) may even be independent of the semantics, for example when the compiler assures that a structure can only ever be accessed by one place in the code, disallowing aliasing on a high level.Hans-Martin Mosner– Hans-Martin Mosner2022年05月25日 15:10:10 +00:00Commented May 25, 2022 at 15:10
-
1Because you semantically want to pass a value and not a reference. This isn't the 90's, passing parameters to functions has basically zero performance impact.JMekker– JMekker2022年05月25日 15:56:56 +00:00Commented May 25, 2022 at 15:56
-
2Other comments provide good reasons but if you wanted to focus solely on performance, please note that references are far from free, particularly in managed languages. So before the overhead of the reference could be justified you typically would need to be dealing with a whole lot more data than 64 bits.Martin Maat– Martin Maat2022年05月25日 20:02:11 +00:00Commented May 25, 2022 at 20:02
-
2The C++ Core Guidelines go into great detail about the appropriateness of various ways to pass parameters. Unless a function knows that the value is cheap to copy, it usually makes sense to take a const ref instead. Of course, as a user of the function you have to trust that it has declared the parameter appropriately.amon– amon2022年05月27日 06:34:30 +00:00Commented May 27, 2022 at 6:34
2 Answers 2
A usual reason to pass by value is when the calling function may or will modify the passed value, and you don't want to see the changes in the caller function.
Imagine, for instance, that a function you call performs a computation on an array of numbers, and was written in a way that, instead of allocating additional memory, it would rather alter the original array. This may be what you want, as you are about to discard the array anyway. Or you may want to continue to use an original array. In this second case, you'll simply pass the array by value, creating indeed a copy of it.
to change the value of operator, we call value of that parameter in place to change the opeatpr directly. Then the function will have ONLY the value but not the address of the passed in variable
Explore related questions
See similar questions with these tags.