For example, this code compiles (g++ 13.1.0) and gives me output "Sum is 20":
#include <iostream>
using namespace std;
void add (int x, int y, int sum);
int main(){
int x = 10, y = 10;
const int sum = 0;
add (x, y, sum);
return 0;
}
void add (int x, int y, int sum) {
sum = x + y;
cout << "Sum is " << sum << endl;
}
I expected the compiler to complain about either trying to pass a constant value to something that's treated as non-constant within the function, or failing to declare sum
as constant in add
. I think I understand everything that's happening here - I'm creating a non-constant copy of a constant variable. I'm just curious why this kind of behavior is permitted.
I think I understand everything that's happening here - I'm creating a non-constant copy of a constant variable.
No and no.
You're copying/assigning the value of a constant variable into a non-constant variable, which is totally ok, e.g.
const int c = 0; //constant variable, define/initialize it
//with the value 0
int i = c; //declare non-constant variable and define/initialize it
//with the value of c
//or
int i; //declare only
i = c; //assign/copy value of c to i
Even this is valid
int i = 0;
const int c = i;
//but
i = 42; //ok
c = 42; //not ok, c is read only
Passing arguments by value to a function is not indifferent to declaring a variable and assigning a value to it. The function argument is local to the function and if it is declared as non const, it can be freely modified.
e.g.
void foo(int sum)
{
sum = 42; //ok, sum is a local non constant variable
}
const int c = 0;
foo(c); //assign/copy the value of c to the variable sum, same as:
//int sum = c;
but
void foo(const int sum)
{
sum = 42; //not ok, sum is a local constant variable,
//read only -> not modifiable
//but
int i = sum;
i += 1; //ok, i is modified not sum
}
int i = 0;
foo(i); //ok, assign/copy the value of i to the variable sum, same as:
//const int sum = i;
const int c = 0;
foo(c); //ok, assign/copy the value of c to the variable sum, same as:
//const int sum = c;
In short: the const
type qualifier is a promise to the compiler, that once the variable is initialized to never be modified again. And the compiler will let you know (via error) if you do so. But once copied into other variables, there might be no promise for those regions of memory (if non const).