5

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.

24n8
  • 1,898
  • 1
  • 12
  • 25
  • See https://softwareengineering.stackexchange.com/questions/204500/when-and-for-what-purposes-should-the-const-keyword-be-used-in-c-for-variables – Matthieu Brucher Dec 18 '18 at 14:07
  • Different question (asks about primitives explicitly), but a related answer https://stackoverflow.com/questions/46292490/is-it-better-to-remove-const-in-front-of-primitive-types-used-as-function-pa – StoryTeller - Unslander Monica Dec 18 '18 at 14:10
  • If a compiler knows that something is const, it can use this information and possibly achieve higher program efficiency due to optimizations (and also prevents you to modify that object accidentally). However, making a passed-by-value parameter `const` in a function declaration does not make sense. On the contrary, it does in a function definition. – Daniel Langr Dec 18 '18 at 14:11
  • @DanielLangr When you say "However, making a passed-by-value parameter const in a function declaration does not make sense. On the contrary, it does in a function definition." I thought the function declaration prototype has to match its respective declaration? Like if you make a declaration with `const` parameters, then your function definition must also use `const` for the parameters? – 24n8 Dec 18 '18 at 14:17
  • @Iamanon Have you looked at the question linked by StoryTeller? Namely his answer: https://stackoverflow.com/a/46292715/580083. – Daniel Langr Dec 18 '18 at 14:19
  • @DanielLangr Just read it. I didn't know that. – 24n8 Dec 18 '18 at 14:20
  • The dupe given as justification for the closure is not a dupe actually. It asks and answers a (slightly) different question. I vote for re-opening – Walter Dec 18 '18 at 18:47

2 Answers2

5

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
{
   ...
}
Walter
  • 44,150
  • 20
  • 113
  • 196
4

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.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483