This question already has answers here:
Undefined behavior and sequence points
(5 answers)
Closed 5 years ago.
When using a single cout to print the same variable updated multiple times, I am getting a weird order of updates. Can anybody explain how such updates are done?
int value = 2;
cout << value << value++ << ++value << endl; // 434
value = 2;
cout << ++value << value++ << value << endl; // 424
value = 2;
cout << value++ << value++ << ++value << endl; // 435
value = 2;
cout << ++value << value++ << value++ << endl; // 532
The order in which expressions in a single statement are executed is undefined. Obviously unless specified via parenthesis or rules of order of execution. For example:
int a[3]{};
int i=1;
a[i] = i++; //undefined if a[1] or a[2]
Behaviour of such code is not defined and depends on compiler and platform in use. Needless to say you should not rely on a certain behaviour of this code.
Related
This question already has answers here:
Restore the state of std::cout after manipulating it
(9 answers)
Closed last year.
I have a simple converting function however the variable is changing.
void convert_print(std::string type,int num)
{
if(type=="oct"){
std::cout << num << " oct value is: " << std::oct << num << endl;
}
else if(type == "hex"){
std::cout << num << " hex value is: " << std::hex << num << endl;
}
}
int main()
{
int num = 30;
convert_print("hex",num);
convert_print("oct",num);
}
Prints
30 hex value is: 1e
1e value is: 30
Why is num getting changed to 1e when I call the function again. I never reassigned num
You haven't told cout to reset the formatting after your last call. This question describes how to restore it. Restore the state of std::cout after manipulating it
This question already has answers here:
Why are `&array` and `array` pointing to the same address?
(2 answers)
How come an array's address is equal to its value in C?
(6 answers)
Closed 1 year ago.
I am confused about array usage as pointer and result of that. Let me explain. When I try this
#include <iostream>
using namespace std;
int main()
{
int a = 10;
int *myPointer = &a;
cout << "*myPointer: \t" << *myPointer << endl;
cout << "myPointer: \t" << myPointer << endl;
cout << "&myPointer: \t" << &myPointer << endl;
cout << "myPointer[0]: \t" << myPointer[0] << endl;
cout << endl;
int myArray[3] = {1,2,3};
cout << "*myArray: \t" << *myArray << endl;
cout << "myArray: \t" << myArray << endl;
cout << "&myArray: \t" << &myArray << endl;
return 0;
}
All of output are exactly what I expected, except last one (&myArray). Lets say my ram something like this:
Address
Variable
Value
0xA100
a
10
0xA101
myPtr
0xA100
0xA102
1
0xA103
2
0xA104
3
0xA105
myArray
0xA102
If I imagine it correctly, then how "&myArray" can be same with "myArray"? Actually, I think it can be anything but 0xA102. Because, this result means that "myArray" is in 0xA102 and value of pointed by myArray is in 0xA102 too. And I know it is weird but it means also, as a value "1", is in 0xA102 too. (At least I got it from this result).
So, I cannot catch the point. I think the result has to be 0xA105 if "&" means address. If yes, why result is not 0xA105. If not, why they have different usage although arrays are pointers.
Is there anybody can clarify the matter?
Thanks.
So my professor told my class to run this program, it supposedly shows what's going on in computer memory. When I ran it, my output file had the same numbers as my professor's output file for the first like 4 lines and then totally different numbers from then on. But this certainly doesn't seem like it's pulling random numbers, because a lot of the output is 0s and a lot of it are large numbers of similar lengths. Can anyone explain this?
#include <iostream>
#include <fstream> // for files
#include <cstdlib> // for exit
#include <climits> // for INT_MAX etc.
int main( )
{
using namespace std;
ofstream outfile;
outfile.open("Whats_in_computer_memory.txt");
cout << "In this program, we declare a small array and then use array syntax " << endl
<< "to see what is in the computer's memory. " << endl
<< " " << endl
<< " " << endl
<< " " << endl
<< " " << endl
<< " " << endl;
int a[1];
int histogram[214749];
for (int i = 0; i < 214749; i++ )
{
histogram[i] = 0;
}
cout << "&a[0] = " << &a[0] << endl
<< "&histogram[0] = " << &histogram[0]<< endl
<< " " << endl;
cout << INT_MAX << endl;
for (int i = 0; i < 1000; i++ )
{
outfile << a[i] << endl;
//cout << INT_MAX/1000000 +a[i]/1000000 << endl;
//histogram[ a[i]/1000000 ]++;
}
for (int i = 0; i < 2 ; i++ )
{
cout << histogram[ i ] << endl;
}
char dummy;
cin >> dummy;
return 0;
}
a has one element. That means
for (int i = 0; i < 1000; i++ )
{
outfile << a[i] << endl;
//cout << INT_MAX/1000000 +a[i]/1000000 << endl;
//histogram[ a[i]/1000000 ]++;
}
is undefined behavior as soon as i >= 1. Once you have undefined behavior anything can happen so we can no longer reason out what is going on.
Your professor is trying to demonstrate that the area of memory around your program contains "stuff" - specifically that the memory around your program isn't zero'd or set to any other default value.
Presumably, this is part of a further point that accessing memory out-of-bounds doesn't guarantee that you'll have any particular value, and as such need to initialise your variables accordingly.
However; the problem is that we consider "accessing out-of-bounds of an array" to be undefined behaviour. Undefined behaviour in the C++ standard means "the compiler can handle this situation in whatever way it considers appropriate". Most compilers will serve you values from nearby memory locations (this being simple to do), but they're not required to do so.
Likewise, some compilers can aggressively optimise-out undefined behaviour (like concluding that i can never be greater than 1 when used to index into a, and adjusting the loop appropriately): compilers are free to assume (for optimisation purposes) that undefined behaviour is never invoked by the programmer. See this page from the LLVM project for more details on undefined behaviour (noting that under "Dereferences of Wild Pointers and Out of Bounds Array Accesses", both the Clang team and g++ have made the same decision with regards to handling out-of-bounds errors: they access nearby memory locations; because it's the simplest thing to do in that case).
This question already has answers here:
Two different values at the same memory address
(7 answers)
Closed 5 years ago.
New to C++ and learning the const_cast — get really confused by the code below:
int main(){
const int j = 1;
int * p = (int *)(&j);
cout << j << ' ' << *p << endl;
cout << &j << ' ' << p << endl;
*p = 2;
cout << j << ' ' << *p << endl;
cout << &j << ' ' << p << endl;
const int k = 1;
int * q = const_cast<int*>(&k);
cout << k << ' ' << *q << endl;
cout << &k << ' ' << q << endl;
*q = 2;
cout << k << ' ' << *q << endl;
cout << &k << ' ' << q << endl;
return 0;
}
The outputs are
1 1
00A2FD9C 00A2FD9C
1 2
00A2FD9C 00A2FD9C
1 1
00A2FD84 00A2FD84
1 2
00A2FD84 00A2FD84
Could anyone tell me why the addresses (&i and p, or &j and q) are the same, but there values (i and *p, or j and *q) are different? I am using Visual Studio 2013RC.
That happens because the compiler can assume a const variable won't change, and hence when your code refers to it, the compiler assumes that using the variable value, or the original value at initialization won't matter, it shoudn't change behavior, so it compiles to what is faster to execute, just using constant 1 without referring to memory locations.
Using const_cast<T*>(obj) to cast away constness and modifying the object is undefined behavior if obj started its life as a constant. In your example you tell the compiler that j isn't going to change and the compiler just replaces all uses of j to become uses of 1, instead. You then break the promise and the code the compiler generated won't pay any attention to you anymore and, instead, does what it pleases.
Please be easy on me and don't shoot me as I'm still newbie.
I'm totally confused and can't for life figure out why when I run this code:
int y = 9;
cout << "++y = " << ++y << "\n--y = " << --y << "\ny++ = " << y++ << "\ny-- = " << y-- << "\n";
cout << "y = " << y << "\n";
I get the following results:
y = 9
++y = 9
--y = 9
y++ = 8
y-- = 9
y = 9
instead of these results:
y = 9
++y = 10
--y = 9
y++ = 9
y-- = 10
y = 9
That I get from this code:
int y = 9;
cout << "y = " << y << "\n";
cout << "++y = " << ++y << "\n";
cout << "--y = " << --y << "\n";
cout << "y++ = " << y++ << "\n";
cout << "y-- = " << y-- << "\n";
cout << "y = " << y << "\n";
Can anyone explain -in simple words as possible- what happens in the first code so that it prints the result that way?
A simple rule is that you are not expected to increment the same location more than once in any given statement. So you should not code cout << y++ << ++y << endl; which contain two increments of y (assuming an int y; declaration).
For details, read about sequence points and undefined behavior in the C++ standard.
There are lot of related questions. Look into them for more!
When according to the rules operation * is to be counted before +, and ++ before *, it will be so.
a*b++ + c // first b++ (returns **old** b), than a*b, than ...+c
But when you have a++ * a--, nobody can tell, what of the two operands, a++ or a-- will be evaluated the first. According to ANSII standard, even if you use the same translator, the result is every time unpredictable.
cite from the C++ ANSII standard:
Except where noted, the order of evaluation of operands of individual
operators and subexpressions of individual expressions, and the order
in which side effects take place, is unspecified. Between the previ-
ous and next sequence point a scalar object shall have its stored
value modified at most once by the evaluation of an expression. Fur-
thermore, the prior value shall be accessed only to determine the
value to be stored. The requirements of this paragraph shall be met
for each allowable ordering of the subexpressions of a full expres-
sion; otherwise the behavior is undefined. [Example:
i = v[i++]; // the behavior is undefined
i = 7, i++, i++; // `i' becomes 9
i = ++i + 1; // the behavior is undefined
i = i + 1; // the value of 'i' is incremented
Sequence points:
at the end of the evaluation of a full expression (a full expression is an expression statement, or any other expression which is not a subexpression within any larger expression);
at the ||, &&, ?:, and comma operators;
and at a function call (after the evaluation of all the arguments, and
just before the actual call).
So, || is a sequence point, but << is not.
Mulitiline version of first code should be:
y = 9;
cout << "y-- = " << y-- << "\n";
cout << "y++ = " << y++ << "\n"
cout << "--y = " << --y << "\n"
cout << "++y = " << ++y << "\n"
cout << "y = " << y << "\n";