4

I have the following function declaration:

void fn(int);

This function has a single integral type parameter. Now, I could call this function by passing a non const or a const integral object. In either case, this function is going to copy the object to its local int parameter. Therefore, any modifications to this parameter is going to be local to the function and is not going to affect the actual arguments of the caller in any way. Now my question is under which scenario will I declare this single int parameter to be of const type? I don't see a need to declare this function as follows.

void fn(const int);

This is because the arguments are going to be anyway passed by value and the function can in no way modify the arguments in either case. I understand that by declaring a parameter constant the function cannot modify it inside its body. However, there is no downside here even if the function modifies since the parameter is local to the function.

naivnomore
  • 1,291
  • 8
  • 14

5 Answers5

5

You're right that to the caller there is no difference -- it only matters inside the function. I prefer to add the const whenever I can. As I'm writing the function, I'm thinking "I want this parameter but have no intention of modifying it (even just locally)" and the compiler will keep me honest.

Also, in some cases the compiler may be able to do more optimizations if it knows the variable is const (as in loop bounds).

Pat Notz
  • 208,672
  • 30
  • 90
  • 92
  • Exactly my argument. I don't believe `const` changes anything to optimization in this context, but it prevents you (or future you) from modifying something that was not meant to be modified in the first place. It's a type of static assertion. I do the same with any variable that I don't wish to modify afterwards, for example `const auto area = width * height;`. – eepp Sep 29 '17 at 03:40
1

Sometimes templates are written in a general way, and end up doing things like that. With function template parameter deduction, though, that const tends to get thrown away.

this is effectively a const argument. It is a pointer, but it's immutable in the sense of your example. (Of course, this is a keyword, not a variable, and unary & doesn't work with it.) If you want an argument to behave like that, declare it const.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
1

Just because it's allowed, doesn't mean there's a point to it.

I wouldn't be surprised if this could cause overloading to behave slightly differently, but I think you're basically right - there's no good outside-the-function reason to do it.

One possible problem is confusing readers who might think you intended a reference instead, but forgot the "&".

  • 1
    In this case, the const makes no difference as far as overloading is concerned. `void f(int)` and `void f(const int)` are the same signature. As for readers, semantically with or without the &, the function behaves the same, so they're free to assume whatever they want and they shouldn't get confused. – Dennis Zickefoose Sep 05 '10 at 03:33
  • @Dennis - on overloading, thanks for the clarification. On "semantically behaves the same", this is debatable for e.g. a large object, or a logically-const class with a mutable cache. Is performance part of the semantics. Still, I kind of agree - I guess my answer is mostly kneejerk because it's something I don't do, so I *want* there to be something wrong with it ;-) –  Sep 05 '10 at 04:08
1

From the C++ Spec: http://www.kuzbass.ru:8086/docs/isocpp/over.html

Parameter declarations that differ only in the presence or absence of const and/or volatile are equivalent. That is, the const and volatile type-specifiers for each parameter type are ignored when determining which function is being declared, defined, or called.

Example:

typedef const int cInt;

int f (int);
int f (const int);              //  redeclaration of  f(int)
int f (int) { ... }             //  definition of  f(int)
int f (cInt) { ... }            //  error: redefinition of  f(int)
sylvanaar
  • 8,096
  • 37
  • 59
0

A favorite interview question in C++ interview is what is the difference between passing by values, passing by pointer and passing by reference.

In this case we are passing by value and that too int and hence it will not matter. But I am not sure about the user created classes. In that case when the compiler see the object is passed by const value it may decide to pass it by the const reference. Nowdays compilers are intelligent and I don't see why they can not do it.

Manoj R
  • 3,197
  • 1
  • 21
  • 36