This is more of a general question:
Is there any point in making a function parameter const
if it is being passed by value?
In a code I am studying, I see a lot of the following:
void some_function(const std::vector<double> some_vec);
std::vector
is passed by value, so what then is the point of the const
?
Like I would understand if the function was instead passing the vector by reference as such:
void some_function(const std::vector<double> &some_vec);
but I see no point in the const
in the former.
When you pass an argument by value, you pass a copy of the value in memory. The function operates on the copy. This means that when a function changes the value of an argument passed by value, the effect is local to that function; the copy changes but the original value in memory is not affected.
A constant argument is the one whose modification cannot take place by the function. Furthermore, in order to make an argument constant to a function, the use of a keyword const can take place like- int sum (const int a, const int b).
Pass-by-references is more efficient than pass-by-value, because it does not copy the arguments. The formal parameter is an alias for the argument. When the called function read or write the formal parameter, it is actually read or write the argument itself.
When you pass an argument by reference, you pass a pointer to the value in memory. The function operates on the argument. When a function changes the value of an argument passed by reference, the original value changes. When you pass an argument by value, you pass a copy of the value in memory.
The point is that you prevent the function body from altering the value. The function argument is just an automatic variable within the function body and you may want to ensure it remains at its input value. Consider
int foo(int x)
{
/* lots of code */
some_other_func(x); // may modify x
/* even more code */
return x+42; // x may have been modified
}
and
int foo(const int x)
{
/* lots of code */
some_other_func(x); // will not compile if x is taken by non-const reference
/* even more code */
return x+42; // x is guaranteed at its input value
}
As a rule of thumb, declare everything const
that is not meant to be altered. Then, if you or somebody accidentally attempts to alter such a variable, a compile-time error will result.
Note also that the const
declarator has no effect in a function declaration, but only in the function definition, i.e. the following is perfectly fine (in fact recommended):
struct bar
{
int foo(int) const;
/* more code */
};
int bar::foo(const int x) const // possibly in another compilation unit
{
...
}
It can be very useful when working with mathematical code in particular, as it stops errant refactorers from changing variables passed in as function parameters. For example, you don't want to mess about with the value of pi (which, annoyingly, is not part of the C++ standard), or things like the gravitational constant, &c.
(In the past I have seen pi *= 2;
as the code was written by a physicist who was convinced that pi ought to be twice as big as most folk would have it.)
It's also nice to have the qualifiers matching in a function declaration and definition (although the language itself doesn't insist on that).
I don't use it much admittedly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With