This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 8 years ago.
I have this code:
#include <iostream>
using namespace std;
int & squareRef(int );
int main() {
int number1 = 8;
cout << "In main() &number1: " << &number1 << endl;
int & result = squareRef(number1);
// cout << "In main() &result: " << &result << endl;
cout << result << endl;
cout << result << endl;
cout << number1 << endl;
}
int & squareRef(int rNumber) {
cout << "In squareRef(): " << &rNumber << endl;
rNumber *= rNumber;
return rNumber;
}
The program produces the following output:
In main() &number1: 0x28ff08
In squareRef(): 0x28fef0
64
1875681984
8
Can anyone please explain why the two "results" are different , is that suppose to be same isn't ?
You are invoking undefined behaviour by returning a reference to a local variable:
test.cc:19:7: error: reference to local variable ‘rNumber’ returned [-Werror=return-local-addr]
int & squareRef(int rNumber) {
rNumber is copied on the stack for the call. After the call, the value on the stack is undefined, and might well change due to subsequent calls. The reference you return only points to that location on the stack and does not hold the actual value.
In general, when these things happen, it is very helpful to turn on all warnings your compiler can give you. With gcc, the flags -Wall -Wextra -Werror provide you with a lot of helpful warnings, such as these. In general, code should compile without throwing any warnings (except maybe unused variables/parameters in function stubs, although there are macros to explicitly skip over these).
Related
This question already has answers here:
How is a variable at the same address producing 2 different values? [duplicate]
(4 answers)
behavior of const_cast in C++ [duplicate]
(3 answers)
Closed 7 years ago.
I'm trying to change value of const variable via its address.
following this code:
#include <iostream>
#include <string>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#include <stdio.h>
using namespace std;
int main(void)
{
uint64_t const x = -1;
uint64_t *b = reinterpret_cast<uint64_t*>(0x28ff10);
cout<< x << endl;
cout<< &x << " " << b << " " << *b << endl;
printf("%p\n", &x);
*b = 10;
cout<< &x << " " << x << " " << b << " " << *b << " " << *(reinterpret_cast<uint64_t*>(0x28ff10)) <<endl;
return 0;
}
Compiled with MinGW 4.8.1:
g++ -g main.cpp && ./a.exe
And this is output:
18446744073709551615
0x28ff10 0x28ff10 18446744073709551615
0028FF10
0x28ff10 18446744073709551615 0x28ff10 10 10
Could anyone explain it ?
EDIT:
Figured out! compile still optimized my variable although I compiled it with -O0. Looked at ASM generated, I saw that printf and cout put directly the value instead of the variable symbol.
So, to make my code do right behavior, I have to declared it with volatile static
I'm trying to change value of const variable via its address.
You've already gone wrong by this point.
const is short for "constant".
You cannot mutate a constant.
Sometimes you can get it to sort of look like you did, but doing so has undefined behaviour. You told your compiler that it can make all sorts of assumptions about x (including optimising it out from your binary entirely!) because you promise that you'll never change it. Then you change it.
No dinner for you tonight, says Mr. Compiler!
This question already has answers here:
What are the differences between a pointer variable and a reference variable?
(44 answers)
Closed 7 years ago.
Can you tell me the difference between the source 1 and 2?
The book says the first one is call by address(pointer) and the second one is call by reference, but i don't exactly get those two sources.
Please explain those sources to me please, thank you in advance.
1.
#include <iostream>
using namespace std;
void absolute(int *a);
void main()
{
int a = -10;
cout << "Value a before calling the main function = " << a << endl;
absolute(&a);
cout << "Value a after calling the main function = " << a << endl;
}
void absolute(int *a)
{
if (*a < 0)
*a = -*a;
}
2.
#include <iostream>
using namespace std;
void absolute(int &a);
void main()
{
int a = -10;
cout << "Value a before calling the main function" << a << endl;
absolute(a);
cout << "Value a after calling the main function" << a << endl;
}
void absolute(int &a)
{
if (a < 0)
a = -a;
}
In terms of what happens at the CPU level, pointers and references are exactly the same. The difference lies in the compiler, it won't let you do a delete on a reference (and there's less typing)
So in your code both functions do the same thing.
This question already has answers here:
unable to print char* pointing to 0
(4 answers)
Closed 9 years ago.
In Visual studio 2012, I was messing around with pointers, and I realized that this program kept crashing:
#include <iostream>
using std::cout;
using std::endl;
int main ()
{
const char* pointer = nullptr;
cout << "This is the value of pointer " << pointer << "." << endl;
return 0;
}
My intent was the set a pointer to nullptr, and then print the address. Even though the program compiles, it crashes during runtime. Can someone explain what is going on?
Also, what's the difference between pointer and *pointer?
You are using a const char* which, when used in std::cout's operator <<, is interpreted as a string.
Cast it to void* to see the pointer's value (the address it contains):
cout << "This the value of pointer " << (void*)pointer << "." << endl;
Or if you want to be pedantic:
cout << "This the value of pointer " << static_cast<void*>(pointer) << "." << endl;
LIVE EXAMPLE
Although you can do cout << "Pointer is " << (void*)pointer << ".\n"; as already been suggested I feel that in this case the "C way" of doing it is prettier (no casting) and more readable: printf("Pointer is %p\n",pointer);
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the correct answer for cout << c++ << c;?
I just ouputted text, when I suddenly noticed.
#include <iostream>
int main()
{
int array[] = {1,2,3,4};
int *p = array;
std::cout << *p << "___" << *(p++) << "\n";
// output is 1__1. Strange, but I used brackets! it should be at
// first incremented, not clear.
p = array;
std::cout << *p << "___" << *(++p) << "\n";
// output is 2_2 fine, why first number was affected? I didn't intend
// to increment it, but it was incremented
p=array;
std::cout << *p << "___" << *(p + 1) << "\n";
// output is 1_2 - as it was expected
p = array;
return 0;
}
Such behaviour is strange for me, why is it so?
You are causing undefined behaviour, so anything can happen and there's no point in speculating about why.
The expression
std::cout<<*p<<"___"<<*(p++)<<"\n"
Is one example: the order of evaluation of all the things between << is unspecified, so *p and *(p++) are unsequenced with respect to each other (i.e. the compiler is not required do do either one first). You are not allowed to modify a variable and then use it without the modification and usage being sequenced, and so this causes undefined behaviour.
The same thing applies to all the other places in that program where a variable is modified and used unsequenced separately in the same expression.
First, sorry for possible question redundancy.
Doing some little experiments with C/C++ pointers in GCC I encountered this somewhat weird behaviour when bypassing constantness of value at the pointer address.
#include <iostream>
int main()
{
using namespace std;
const double number = 100;
//bypassing constantess of pointed-to value
double * pointer_to_value = (double *) &number;
*pointer_to_value += 200;
cout << "Adress of number: " << &number << "\tValue of number: " << number << endl <<
" Pointer value: " << pointer_to_value << "\tDereferencing pointer: " << *pointer_to_value;
return 0;
}
I would expect both form of checking the value yielding same results. Location of value is same in both cases. Program generates following output, however:
Adress of number: 0x22ff30 Value of number: 100
Pointer value: 0x22ff30 Dereferencing pointer: 300
Anyone capable of explaining?
Thanks in advance.
It's undefined behaivor.
It's irrelevant why exactly it happens (actually because the compiler inlines the value).
"UnConsting” const value via pointer is a Undefined Behavior.
So it is not posible to define a behavior not defined by the Standard.
Compiler optimization. Compiler doesn't expect you to try and trick it like that, it knows that the value is const, so it just cached it. Try to compile it without any optimization, and see if it makes any difference.
Generally the meaning of const is:
constant - the object shall not be modified. Attempt to do so results in undefined behavior. On most of the compilers it is compile-time error.
Compiler optimization. You can overcome that by adding volatile keyword to the variable.
#include <iostream>
int main()
{
using namespace std;
volatile const double number = 100;
//bypassing constantess of pointed-to value
double * pointer_to_value = (double *) &number;
*pointer_to_value += 200;
cout << "Adress of number: " << &number << "\tValue of number: " << number << endl <<
" Pointer value: " << pointer_to_value << "\tDereferencing pointer: " << *pointer_to_value;
return 0;
}
My guess is that gcc has done some optimizations on your behalf, replacing the reference to << number with << 100. Should be possible to verify by looking at the generated asm code.