This question already has answers here:
const_cast doesn't work c++? [duplicate]
(3 answers)
Closed 6 years ago.
After const_cast, the value does not change in the main function. But changes when calling an external function, still prints the old value in the main (where const int is initialized first).
int main() {
const int i = 5;
int* p = const_cast<int*>(&i);
*p = 22;
std::cout<<i;
return 0;
}
Output is 5, why? The watch-window shows value of i = 22:
So why does it print 5 ? The output differs if I call an external function:
void ChangeValue(const int i) {
int* p = const_cast<int*>(&i);
*p = 22;
std::cout<<i; //Here the value changes to 22
}
int main() {
const int i = 5;
ChangeValue(i); //Value changes to 22 in the ChangeValue function
std::cout<<i // It again prints 5.
}
Why is the value not changed even if the value changes after calling the ChangeValue function?
I get the same output on a Linux Platform. Could someone please add clarity to my confusion?
Trying to modify a constant value leads to undefined behavior, just don't do it.
As for why it doesn't change, the compiler sees that it is a compile-time constant and may store it in a read-only segment.
For the second program, the variable i can't be stored in a read-only segment, it's stored on the stack like any other local variable. However, since you marked i as constant attempting to modify it is still undefined behavior.
The reason the main program prints the old value, is because you pass the variable by value meaning it gets copied into the local variable i in the ChangeValue function. If the variable wasn't a constant in the main or the ChangeValue function, the value of i in the main function would still not change.
If you change the ChangeValue function to take its argument by reference, you might get the same behavior as the first program.
Related
In the following call-by-value example, I cannot understand why this code is not changing the value of the 5 to a 6.
Line 11 calls the function changeValue which has the value 6, so I would have thought 6 should be output, however 5 is still output?
#include <iostream>
using namespace std;
void changeValue(int value);
int main()
{
int value = 5;
changeValue(value);
cout << "The value is : " << value << "." << endl;
return 0;
}
void changeValue(int value)
{
value = 6;
}
// This doesn't change the value from 5 to 6. 5 is output?
When you pass a function argument by value a copy of the object gets passed to the function and not the original object.Unless you specify explicitly arguments to functions are always passed by value in C/C++.
Your function:
void changeValue(int value)
receives the argument by value, in short a copy of value in main() is created and passed to the function, the function operates on that value and not the value in main().
If you want to modify the original then you need to use pass by reference.
void changeValue(int &value)
Now a reference(alias) to the original value is passed to the function and function operates on it, thus reflecting back the changes in main().
The value of value isn't changing because your int that you pass to the function is being copied into the stack frame of the function, then it's being changed, and when the function exits the copy is destroyed. The original in main's stackframe has not changed, since it was copied to the changeValue.
If you want to change it, you should pass a reference to an int, like so void changeValue(int& value), which says that the value isn't copied into the function, but merely an alias to the original is passed.
The behavior being observed currently is because passing by value means a copy of value (new integer with value of value) is actually passed to the function.
You have to pass by reference. For that the changeValue function will look like this:
void changeValue(int& value)
Rest of the code will remain the same.
Passing a variable by reference means the same int value declared in main is passed to the changeValue function.
Alternatively, you can pass a pointer to value to the changeValue function. That will however, require changes to how you call the function also.
int main()
{
int value = 5;
changeValue(&value);
...
return 0;
}
void changeValue(int* value)
{
*value = 6;
}
I'm including this answer as another way to think about writing functions and passing parameters by value.
You could also have written this code in the following way. That is pass the parameter by value, modify the local copy in the function, which does not alter the original value, and return the altered value.
int changeValue(int val)
{
val = 6;
return val;
}
int main()
{
int value = 5;
value = changeValue(value);
cout << "The value is : " << value << "." << endl;
return 0;
}
I am not in any way indicating my suggestion for your program is better than passing by reference. Instead, it is just the way learning a functional programming language (Clojure) is affecting the way I think.
Also, in languages like Python, you cannot modify a scalar parameter. You can only return a new value. So my answer is more of an exercise in thinking about things differently in C/C++.
AND:
the copy is assigned 6, but the change is not returned.
you need some reference or pointer if you want to change the value:
try using a method signature like:
void changeValue(int& value)
that will probably do what you expected
This is because the change in the changeValue () function is local. When you can changeValue (value) the contents of the variable value in main is copied in the formal argument named value (same name) of the function. Same name does not mean that the both are same. The value you are accessing inside the function is a copy of the value you had in the main.
To change you either need to pass it by reference or a pointer
void changeValue (int *val)
{
*val = 6;
}
call with changeValue (&value) in main
This works because the address of the variable value in main is passed and this address value is copied into val of the function. By doing *val we can get the contents of the address which was copied into val, which in actually the contents of value in main.
OR
void changeValue (int &val)
{
val = 6;
}
This question already has answers here:
What is array to pointer decay?
(11 answers)
Closed 5 years ago.
In the following program, the value of the first element of array x prints as zero after passing the array as parameter to some function which modifies its parameters. The same does not happen to the int variable y, a modification in another function goes unnoticed in the calling function. Thus I was expecting the array to retain its values before the function call, just like it happens with y. Why is the array changed while the variable is not?
void func1 (int x[]){
x[0]=0;
}
void func2(int y){
y=0;
}
int main(){
int x[]={7}, y=8;
func1(x);
func2(y);
cout << x[0] << y;
return 0;
}
output:
08
expected:
78
The parameter int[] is exactly the same as int*, a pointer to an int. The array passed to the function decays to such pointer to the first element of the array, thus dereferencing it through the subscript operator and modifying the int pointee results in the original being modified.
for you information i am putting values in comment in front of every line
void func1 (int x[]){
x[0]=0;//x here has same address as in main function so changes can be //directly apply to the original value of x array
//x[0]=7 was passed in this function is now modified by have a value x[0]=0
}
void func2(int y){
y=0;//but y is a different variable in this function it is not the same y in main function so if you change its value it does not mean that you are changing the value of y in main function so it does not give you the expected output
// it is due to local variable concept y in func2 is different and y in main is a different so all you have to do is to pass address of y variable so that if you want to change any thing is y will directly change its value in main function
}
int main(){
int x[]={7}, y=8;
func1(x);
func2(y);
cout << x[0] << y;
return 0;
}
Array use contiguous memory location to store data.
When you are calling func1(int x[]) then the previous value changing with value given by function and the location remaining same, so
in main function
x[0]=7
after function call
x[0]=0
thats why your array value getting changed.
And for the variable you didn't return anything thats why no change for it.
So 08 is correct output for this case
I recently read about references in C++. I am aware of basic properties of references but I am still not able to figure out why following two programs produce different output.
#include<iostream>
using namespace std;
int &fun()
{
static int x = 10;
return x;
}
int main()
{
fun() = 30;
cout << fun();
return 0;
}
This program prints 30 as output. As per my understanding, the function fun() returns a reference to memory location occupied by x which is then assigned a value of 30 and in the second call of fun() the assignment statement is ignored.
Now consider this program:
#include<iostream>
using namespace std;
int &fun()
{
int x = 10;
return x;
}
int main()
{
fun() = 30;
cout << fun();
return 0;
}
This program produces the output as 10. Is it because, after the first call, x is assigned 30, and after second call it is again overwritten to 10 because it is a local variable? Am I wrong anywhere? Please explain.
In the first case, fun() returns a reference to the same variable no matter how many times you call it.
In the second case, fun() returns a dangling reference to a different variable on every call. The reference is not valid after the function returns.
When you use
fun() = 30;
in the second case, you are setting the value of a variable that is not valid any longer. In theory, that is undefined behavior.
When you call fun() the second time in the second case, the variable x is set to 10. That is independent of the first call to the same function.
Just adding to what has been said. The reason behind the first case's behavior is because it is a static variable, which has a static duration. Static duration means that the object or variable is allocated when the program starts and is deallocated when the program ends.
This means that once x in the first case has been initialized the first time with 10, the next function call will ignore static int x = 10; because x cannot be instantiated again, as it has already been allocated, and will simply proceed to return x;, which will be the same x that was assigned 30 in main.
Basically, your understanding is right, except for in 2nd case, you're processing a dangled reference of the local variable has been invalid, which is undefined behaviour, means anything is possible. What you said is just one of the possibility, it also could result in others, such as getting a random number, program crash, etc.
While I was learning about const variables in c++, I tried this :
#include <iostream>
int main()
{
const int p = 20;
int* a = const_cast<int*>(&p);
*a = 10;
std::cout<<"Value at a: "<<(*a)<<std::endl;
std::cout<<"Value of p: "<<p<<std::endl;
std::cout<<"Their addresses : "<<std::endl;
std::cout<<a<<" "<<&p<<std::endl;
return 0;
}
and it produces the output:
Value at a: 10
Value of p: 20
Their addresses :
0x7fff4646d7d4 0x7fff4646d7d4
Seemingly I assigned the value 10 to the memory address of p, but their values come out different. Why is it so?
Attempting to modify an object that was originally declared const gives you undefined behaviour.
ยง7.1.6.1/4 [dcl.type.cv] Except that any class member declared mutable can be modified, any attempt to modify a const object during its lifetime results in undefined behavior.
Chances are, your compiler is replacing all occurences of p in your code with the value 20, since you have promised that it will not change. So the line that prints p has changed to:
std::cout<<"Value of p: "<<20<<std::endl;
So it prints 20 regardless of whether you modified the original object. Of course, since you have undefined behaviour, this kind of reasoning is fruitless and you should not invoke undefined behaviour in your program.
In the following call-by-value example, I cannot understand why this code is not changing the value of the 5 to a 6.
Line 11 calls the function changeValue which has the value 6, so I would have thought 6 should be output, however 5 is still output?
#include <iostream>
using namespace std;
void changeValue(int value);
int main()
{
int value = 5;
changeValue(value);
cout << "The value is : " << value << "." << endl;
return 0;
}
void changeValue(int value)
{
value = 6;
}
// This doesn't change the value from 5 to 6. 5 is output?
When you pass a function argument by value a copy of the object gets passed to the function and not the original object.Unless you specify explicitly arguments to functions are always passed by value in C/C++.
Your function:
void changeValue(int value)
receives the argument by value, in short a copy of value in main() is created and passed to the function, the function operates on that value and not the value in main().
If you want to modify the original then you need to use pass by reference.
void changeValue(int &value)
Now a reference(alias) to the original value is passed to the function and function operates on it, thus reflecting back the changes in main().
The value of value isn't changing because your int that you pass to the function is being copied into the stack frame of the function, then it's being changed, and when the function exits the copy is destroyed. The original in main's stackframe has not changed, since it was copied to the changeValue.
If you want to change it, you should pass a reference to an int, like so void changeValue(int& value), which says that the value isn't copied into the function, but merely an alias to the original is passed.
The behavior being observed currently is because passing by value means a copy of value (new integer with value of value) is actually passed to the function.
You have to pass by reference. For that the changeValue function will look like this:
void changeValue(int& value)
Rest of the code will remain the same.
Passing a variable by reference means the same int value declared in main is passed to the changeValue function.
Alternatively, you can pass a pointer to value to the changeValue function. That will however, require changes to how you call the function also.
int main()
{
int value = 5;
changeValue(&value);
...
return 0;
}
void changeValue(int* value)
{
*value = 6;
}
I'm including this answer as another way to think about writing functions and passing parameters by value.
You could also have written this code in the following way. That is pass the parameter by value, modify the local copy in the function, which does not alter the original value, and return the altered value.
int changeValue(int val)
{
val = 6;
return val;
}
int main()
{
int value = 5;
value = changeValue(value);
cout << "The value is : " << value << "." << endl;
return 0;
}
I am not in any way indicating my suggestion for your program is better than passing by reference. Instead, it is just the way learning a functional programming language (Clojure) is affecting the way I think.
Also, in languages like Python, you cannot modify a scalar parameter. You can only return a new value. So my answer is more of an exercise in thinking about things differently in C/C++.
AND:
the copy is assigned 6, but the change is not returned.
you need some reference or pointer if you want to change the value:
try using a method signature like:
void changeValue(int& value)
that will probably do what you expected
This is because the change in the changeValue () function is local. When you can changeValue (value) the contents of the variable value in main is copied in the formal argument named value (same name) of the function. Same name does not mean that the both are same. The value you are accessing inside the function is a copy of the value you had in the main.
To change you either need to pass it by reference or a pointer
void changeValue (int *val)
{
*val = 6;
}
call with changeValue (&value) in main
This works because the address of the variable value in main is passed and this address value is copied into val of the function. By doing *val we can get the contents of the address which was copied into val, which in actually the contents of value in main.
OR
void changeValue (int &val)
{
val = 6;
}