0
#include <iostream>

int square(int const &i) {    
  return i * i;
}

int main() {   
  int side = 5;
  std::cout << square(side) << "\n"; 
}

Just looking at some code and this is a basic question but the const doesn't really do anything here does it? I mean it ensures that I can't change the value of i but I mean it's kinda useless isn't it?

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
  • 4
    The point isn't so much that you can't change `i`, it's that the caller of the function *knows* you can't change `i`. – Mark Ransom Aug 30 '21 at 19:16
  • @drescherjm: I wouldn't say it's good practice to pass an `int` by const reference vs. passing it by value. – Fred Larson Aug 30 '21 at 19:16
  • 1
    Yes I would have just passed `i` by value in this case. – drescherjm Aug 30 '21 at 19:17
  • 1
    @FredLarson it's actually quite common in template code where you don't know the type of the parameter until the template parameter is specified. You don't know if the type will be trivial to copy like `int` or incredibly expensive. – Mark Ransom Aug 30 '21 at 19:17
  • No point to pass-by-reference either. Hopefully the compiler can optimize that right out. – Eljay Aug 30 '21 at 19:18
  • 1
    @MarkRansom: Absolutely, but this isn't a template. – Fred Larson Aug 30 '21 at 19:19
  • 1
    So just int i makes more sense in this specific piece of code? passing it a const reference is just unnecessary? –  Aug 30 '21 at 19:20
  • @tommyboyl01 Correct. – eerorika Aug 30 '21 at 19:43
  • const reference is good if the object passed is larger than a reference or pointer. I believe the standard does not describe how a reference is implemented but many times it will be the size of a pointer. In 64 bit code a pointer is likely 64 bits but an int may be 32 bits making pass by reference possibly more costly than pass by value. – drescherjm Aug 30 '21 at 19:46
  • Related: [https://stackoverflow.com/questions/2582797/why-pass-by-const-reference-instead-of-by-value](https://stackoverflow.com/questions/2582797/why-pass-by-const-reference-instead-of-by-value) – drescherjm Aug 30 '21 at 19:50
  • Notice that the question doesn't ask why use a const reference instead of passing by value. It asks simply why there is a `const`. I think perhaps the question is much simpler than the discussion is giving it credit for. – Tim Randall Aug 30 '21 at 19:57

5 Answers5

4

I mean it ensures that I can't change the value of i

Yes, that is what it does.

but I mean it's kinda useless isn't it?

In this example it's not useful, but imagine that your function was 300 lines long instead of 1 line long, and was being maintained over several years by multiple different programmers of varying skill levels.

When looking at code in the middle of a big function like that, it's often very useful to know what the value of i will be on a given line. If i has been marked as const, then it's easy to know that the value of i is guaranteed to be equal to the value that was passed in to the function, because the compiler (more-or-less) guarantees that to you; if any of the code earlier in the function had tried to assign a different value to i, the function would not have compiled. Without the const tag, on the other hand, you'll have to manually read through all the code earlier in the function to verify "by eye" that none of that code assigned a different value to i, or if it did, under what circumstances that might occur and what new value it might assign. That's a lot of extra programmer-time, and assignments like that might be very easy to miss.

Hence, the const tag can be a real time-saver for programmers, in some cases.

A second benefit is that with the const tag you can call the function with a temporary-value as an argument, like this:

square(9)

... whereas without the const the above would be a compile-time error. (In this case you could get also around that error by changing the argument type to a simple int or const int instead of an int &, but in general you often want to pass by-reference to avoid unnecessary copying of objects during function-calls)

Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234
  • Why exactly do i get a compile-time error when I call square(9) without the const? –  Aug 30 '21 at 19:32
  • C++ makes it a compile-time error to pass a temporary-object by non-const-reference because 99% of the time, making a change to a temporary-object is not a useful thing to do; I believe that the reasoning is that if you're changing an object that is going to be destroyed as soon as the function returns, you're performing a useless operation and therefore they should catch that problem at compile-time rather than forcing you to debug it at run-time. (see also: https://stackoverflow.com/questions/27463785/cant-pass-temporary-object-as-reference ) – Jeremy Friesner Aug 30 '21 at 19:34
  • Thanks you really helped –  Aug 30 '21 at 19:37
  • `I mean it ensures that I can't change the value of i. Yes, that is what it does.` Technically no, i that isn't ensured. – eerorika Aug 30 '21 at 19:39
  • @eerorika that's true; a programmer could still use `const_cast` or (since it's being passed by-reference) a separate non-const reference to the same memory location to "cheat" and change the value anyway. I didn't want to get into the weeds with that, though, since it might make my answer more confusing that it needed to be. – Jeremy Friesner Aug 30 '21 at 19:41
0

This isn't useless because later on you will be studying copy constructor where you will study about Deep copy and Shallow copy. This concept of const is very useful and helpful. If you are using it in your early days of C++, Trust me, you will be really happy in future.

0

In this case the optimizer can see both functions so performance-wise it will have no effect.
However if the optimizer cannot see the definition of square while compiling main, and you would have used side again, then there would a difference.
In the const case all reads from side would have been constant folded to 5.
In the non const case, after calling square, all reads from side would have to read the variable because square might have changed it.

Daniel
  • 30,896
  • 18
  • 85
  • 139
0

I mean it ensures that I can't change the value of i

Technically, it does not ensure that. It is conventional that a function accepting a reference to const should not modify the referred object, and it is harder to accidentally modify the referred value, but there is no guarantee and the function can change the value. I would recommend to conform to that convention whenever possible (and it nearly always is possible).

It is kinda useless to use a reference parameter in this case.

eerorika
  • 232,697
  • 12
  • 197
  • 326
-1

As you guessed, there is no point to make the i variable const.

There is, as far as I know, one reason for that :

  • i is type int, which is smaller than the pointer/reference size, there is no need to pass by ref, actually a pass by value is more efficient.
bad_coder
  • 11,289
  • 20
  • 44
  • 72
Jee4404
  • 1
  • 3
  • 2
    *...actually a pass by value is more efficient.* It *may* be more efficient. It may result in the exact same code, especially when `-O3` optimizations are enabled. – Eljay Aug 30 '21 at 19:21