There are several benefits:

* it clarifies your intention: everybody will understand that this variable is not supposed to vary.
* it avoids stupid mistakes, where a typo would have caused your value to change
* it forces discipline: if you use pointers or references to that variable, the compiler will complain if it is a non const pointer or reference, that could lead to subtle errors.
* it allows the compiler to make assumptions and optimizations, that could otherwise not be made in certain circumstances.

Let me develop the last point with a small and silly example:

 extern void f(int *p); // function f() takes a non const pointer
 
 int main()
 {
 int k = 10; 
 f(&k); // the compiler has to assume that f() could change k
 int i = k*k+2*k+1; // the compiler has to make the operation
 std::cout<<i; 
 }

The relevant part of [the assembly][1] looks like: 

 mov DWORD PTR [rsp+12], 10 // store value in k
 call f(int*)
 mov eax, DWORD PTR [rsp+12] // load the potentially changed k
 lea esi, [rax+2] // and make the computation
 imul esi, eax
 add esi, 1 // here we are ready to display value


Now the same code with const would look like: 

 int main()
 {
 const int k = 10; 
 f(const_cast<int*>(&k)); // we have to be sure about the cast!! 
 int i = k*k+2*k+1; 
 std::cout<<i; 
 }

Of course, to write this we have to know that f() will not change the value pointed at (if not it would be undefined behavior). But the compiler could then [generate][2]: 

 mov DWORD PTR [rsp+12], 10
 call f(int*)
 mov esi, 121 // the compiler could make the calculation upfront! 


 [1]: https://godbolt.org/g/gmJnAc
 [2]: https://godbolt.org/g/wbCLBV