Variable has two values simultaneously? - c++

I ran into this example online and I can't figure out how it works for the life of me.
#include <iostream>
int main()
{
int const a = 1;
int* pa = (int*) &a;
*pa = 2;
printf("%p %d %p %d", (void*) &a, a, (void*) pa, *pa);
return 0;
}
When I compile it on my machine, I get:
0xffffcc04 1 0xffffcc04 2
Which means that the memory location 0xffffcc04 has value 1 and 2 simultaneously??? Is the compiler optimizing away a, or am I missing something?
P.S. when I run this in debug, a and *pa are 2...

Changing a const-value yields undefined behaviour, and the "mysterious" output is just such undefined behaviour.
It is actually needless to investigate on why a behaviour in the world of undefined behaviour is as it is then. But in your case it is probably not using a as you declare it as const, so the compiler "knows" the value and may decide not to access the variable.
Just for showing something curious, try:
int main()
{
volatile int const a = 1;
int* pa = (int*) &a;
*pa = 2;
printf("%p %d %p %d", (void*) &a, a, (void*) pa, *pa);
return 0;
}

Related

Why does the following result in segmentation fault?

const int* additional(int* s, int* f){
const int* ts = reinterpret_cast<const int*>(*s + *f);
return ts;
}
int main() {
int a = 10, b = 20;
const int* oc = additional(&a, &b);
std::cout << *oc;
return 0;
}
I've tried using static, although it produces the same error
There are many things wrong with your code.
*s + *f is an int, not a pointer (you add the dereferenced values).
you are doing a reinterpret cast which isn't needed at all. Just pass the int's directly without pointers and you are good to go.
const int additional(int s, int f){
return s + f;
}
int main() {
int a = 10, b = 20;
const int oc = additional(a, b);
std::cout << oc;
return 0;
}
You reinterpret the number 30 as a pointer to const int and attempt to read through the reinterpreted pointer. The operating system noticed that the process was attempting to access an address wasn't mapped for the process and sent the segfault signal to terminate the process in order to protect the badly behaving process from itself.
Reinterpret casting is unsafe. Don't use it unless you know what you're doing. And when you know what you're doing, you'll know that it's quite rare to need to use it.
I was aiming to shorten the int t = *f + *s;
That is already extremely short. The function that you defined is much longer and so is even a call to the function. Note that the initialiser expression that you quote has type int while your function returns const int*. That, along with the broken reinterpret cast are the problem.
If you wanted to make the indirection shorter, then how about using references instead of pointers:
const int& f = a;
const int& s = b;
int t = a + b; // shorter

Strange output after cast removing constness in C++

After encountering some cast and const issues, I have simplified my problem in a very small code snippet:
#include <iostream>
using namespace std;
int main()
{
const int a = 2;
const int* p = &a;
int* p_bis = (int*)p;
*p_bis = 42;
printf("\na = %d", a);
printf("\n&a = %p\n", &a);
printf("\np = %p", p);
printf("\n*p = %d\n", *p);
printf("\np_bis = %p", p_bis);
printf("\n*p_bis= %d", *p_bis);
}
After compiling this in C++17, it gives me the following output:
a = 2
&a = 0x7ffe9924d19c
p = 0x7ffe9924d19c
*p = 42
p_bis = 0x7ffe9924d19c
*p_bis= 42
I know that the line int* p_bis = (int*)p; is very dirty, because I do a C cast instead of a clean C++ cast, and furthermore I remove the constness with my cast. But What I don't understand however is how is it possible to have 2 values at the same address 0x7ffe9924d19c. Is it just some undefined behavior, and there is nothing else to understand?
While it is perfectly valid to cast a const pointer to a non-const one, and it also is valid to modify data through that pointer if the data was not originally defined as const, it is invalid to do so if the data was originally defined as const (which is your case). Changing the value of a variable that was defined as const (even through indirection) is undefined behavior.
The above applies to any version of both C and C++.

const in body of C++ functions

I realized, what if i define const int into the body of c++ function and then use the address arithmetic to change the value of the constant( its on the stack, isn't it? ). i got this code:
const int a = 10;
int b = 100;
int * c = &b;
c++;
cout << "&a: " << &a << endl;
cout << " c: " << c << endl;
*c = 100500;
cout << " a: " << a << endl;
cout << "*c: " << *c << endl;
and i got this output
&a: 0x7ffff63866a8
c: 0x7ffff63866a8
a: 10
*c: 100500
So, addresses are the same, but values are different. Can someone explain me this result? Thanks!
p.s. i tried on GCC, Clang and VS
Can someone explain me this result?
As with any attempt to access objects in invalid ways via invalid pointer arithmetic or other shenanigans: undefined behaviour.
What is happening here is that the compiler is assuming that the value of a won't change, and optimising it to be a compile-time constant. It's allowed to do that, since you've declared it const and thereby stated that it won't change.
its on the stack, isn't it?
Since you also take the address of it (when you print &a), it does get allocated an address on the stack; but there's no need for the program to read from that address to get the value, since it's already known to be 10.
Of course, this is all undefined, so the program would be just as valid if it ordered you a pizza instead.
Your program has undefined behavior written all over it...
The assumption that incrementing the address of b will get you to a is bogus, it could or it could not. You are then using what is called in the standard unsafely derived pointer to modify a const object (a) which is also undefined behavior. Anything can happen.
What really happens (in your implementation, explanation of your results but you cannot depend on this as this is undefined behavior) is that you forced the allocation of a in the stack by means of taking its address, and you got a pointer into it. You modified that value, and the address in memory is updated. But, in the expression: cout << " a: " << a << endl; the compiler knows that a is a constant, and thus its value can only be 10, so it transformed the code into cout << " a: " << 10 << endl; to avoid having to go to memory to obtain the value.
const int a = 10;
int b = 100;
OK.
int * c = &b;
OK, but silly and my bug-o-meter is starting to twiddle.
c++;
Bug-o-meter now in the yellow zone.
cout << "&a: " << &a << endl;
OK
*c = 100500;
Bug-o-meter pegged. Undefined Behavior invoked. World explodes, you get fired.
c++ moves the pointer to the next int in memory. The pointer math is OK, but all you can use c for at this point is to compare the pointer to another pointer. You can't dereference the pointer in any way. But that's what you do when you try to assign through it.
What happens next is irrelevant and, honestly, misleading. You think that c now points to the same memory as b, and maybe it does. But it's only through Undefined Behavior that this happened. You might also think that the value of *c is what you expect it to be, but this result is false. Maybe it is, maybe it isn't. You shattered the vial when you opened the box -- the cat is dead. And so is your program.
And by the way, if what you're trying to do is find a way to cheat the compiler so that you can change a const, don't -- it is strictly forbidden to change a const by any means.
There is a const_cast in C++, but that is also not a mechanism that you can use to change a const.
its on the stack, isn't it?
No, your expectations are wrong. C++ has no notion of stack whatsoever, much less of how different automatic variables are stored in memory relative to each other. What you are trying to do is plain Undefined Behaviour.
In your very case, the compilers optimize a away, because they are allowed to by the standard, and the results you're getting don't have to make any sense since it's UB anyway.
The C++ compiler will simply assume that you will never try to change the value of a const variable.
This doesn't mean that if you do you will get an error... just that the compiler authors can ignore what is going to happen and anything that happens will be classified as "your fault".
SSCC:
#include <stdio.h>
int main ()
{
const int a = 10;
int b = 100;
int *c = &b;
printf ("a=%d, b=%d, *c=%d; &a=%p, &b=%p, c=%p\n",
a, b, *c, (void *)&a, (void *)&b, (void *)c);
c++; // "c" now invalid
printf ("a=%d, b=%d, *c=%d; &a=%p, &b=%p, c=%p\n",
a, b, *c, (void *)&a, (void *)&b, (void *)c);
*c = 100500; // Undefined behavior!
printf ("a=%d, b=%d, *c=%d; &a=%p, &b=%p, c=%p\n",
a, b, *c, (void *)&a, (void *)&b, (void *)c);
return 0;
}
EXAMPLE OUTPUT:
a=10, b=100, *c=100; &a=0028FF18, &b=0028FF14, c=0028FF14
a=10, b=100, *c=10; &a=0028FF18, &b=0028FF14, c=0028FF18
a=10, b=100, *c=100500; &a=0028FF18, &b=0028FF14, c=0028FF18
CASE 2 - WE DON'T TRY TO TAKE ADDRESSOF CONST A:
#include <stdio.h>
int main ()
{
const int a = 10;
int b = 100;
int *c = &b;
printf ("a=%d, b=%d, *c=%d; &b=%p, c=%p\n",
a, b, *c, (void *)&b, (void *)c);
c++; // "c" now invalid
printf ("a=%d, b=%d, *c=%d; &b=%p, c=%p\n",
a, b, *c, (void *)&b, (void *)c);
*c = 100500; // Undefined behavior!
printf ("a=%d, b=%d, *c=%d; &b=%p, c=%p\n",
a, b, *c, (void *)&b, (void *)c);
return 0;
}
SAMPLE OUTPUT
a=10, b=100, *c=100; &b=0028FF14, c=0028FF14
a=10, b=100, *c=2686744; &b=0028FF14, c=0028FF18
a=10, b=100, *c=0; &b=0028FF14, c=00018894

What's the difference between global and local pointers?

I have a small code something like this:
#include <stdio.h>
int *ptr1;
int *ptr2;
void some_function(void)
{
int B = 5;
ptr2 = &B;
}
main (){
int C, D;
int A =10;
int *ptr3;
ptr1= &A;
ptr3=ptr2;
some_function();
C = *ptr1 + *ptr2;
printf("Sum of the numbers C= %d\n",C);
some_function();
D = *ptr1 + *ptr3;
printf("Sum of the numbers D= %d\n",D);
}
Why dont I get the result for D but get the result for C? I get the result for the print statement Sum of the numbers C=15 but nothing for the last print statement for D. What is the difference between local and global pointers ( I mean both ptr1 and ptr2 are defined global and ptr3 is define local)? Is the pointer assignment ptr3=ptr2 valid? are there any significant difference with pointer to local variable Vs. pointer to global variable ?
ptr3 = ptr2;
ptr3 is initialized with the value of ptr2 which is NULL. It is NULL because you didn't initialize it and it has static storage duration.
then you do
D = *ptr1 + *ptr3;
You are dereferencing ptr3 which is a null pointer: this is undefined behavior. The value of ptr2 may have changed during your program, but ptr3 is still a null pointer.
EDIT: For the sake of completeness (well, sort of):
void some_function(void)
{
int B = 5;
ptr2 = &B;
}
B object lifetime ends when the functions some_function exits. You cannot access B through ptr2 after some_function has returned. It means:
C = *ptr1 + *ptr2;
also invokes undefined behavior because you are dereferencing ptr2 which is an invalid pointer in this statement.
ptr3=ptr2; coped before the call of function some_function(); so wrong address assigned to ptr3 that is NULL because ptr2 is 0 (by-default value of global variable).
Do like this:
some_function();
ptr3=ptr2;
D = *ptr1 + *ptr3;
printf("Sum of the numbers D= %d\n",D);
Also, following code running correct because ptr2 value is used after call of some_function(); function.
some_function();
C = *ptr1 + *ptr2;
printf("Sum of the numbers C= %d\n",C)
Ooh!, Scope of variable ptr2 points to local to some_function().
void some_function(void)
{
int B = 5;
ptr2 = &B;
}
Do like this:
void some_function(void)
{
int* B = calloc(1,sizeof(int));
*B = 5;
ptr2 = B;
}
Also don't forget to free(ptr2) after print statement;

How *restrict / *__restrict__ works in C / C++?

Here is some code I wrote (using GCC's __restrict__ extension to C++):
#include <iostream>
using namespace std;
int main(void) {
int i = 7;
int *__restrict__ a = &i;
*a = 5;
int *b = &i, *c = &i;
*b = 8;
*c = 9;
cout << **&a << endl; // *a - which prints 9 in this case
return 0;
}
Or, the C version (in case the C++ version is not clear due to the use of an extension which every popular C++ compiler supports), using GCC:
#include <stdio.h>
int main(void) {
int i = 7;
int *restrict a = &i;
*a = 5;
int *b = &i, *c = &i;
*b = 8;
*c = 9;
printf("%d \n", **&a); // *a - which prints 9 in this case
return 0;
}
From what I've read, if I do *a = 5, it changes the value of the memory he, a, is pointing to; after that, the memory to which he is pointing to should not be modified by anyone else except a, which means that these programs are wrong because b and c modify it after that.
Or, even if b modifies i first, after that only a should have access to that memory (i).
Am I getting it correctly?
P.S: Restrict in this program doesn't change anything. With or without restrict, the compiler will produce the same assembly code. I wrote this program just to clarify things, it is not a good example of restrict usage. A good example of restrict usage you can see here: http://cellperformance.beyond3d.com/articles/2006/05/demystifying-the-restrict-keyword.html
No.
Statements
*b = 8;
*c = 9;
will cause undefined behavior.
From documentation:
A pointer is the address of a location in memory. More than one pointer can access the same chunk of memory and modify it during the course of a program. The restrict type qualifier is an indication to the compiler that, if the memory addressed by the restrict-qualified pointer is modified, no other pointer will access that same memory. The compiler may choose to optimize code involving restrict-qualified pointers in a way that might otherwise result in incorrect behavior. It is the responsibility of the programmer to ensure that restrict-qualified pointers are used as they were intended to be used. Otherwise, undefined behavior may result.