Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 months ago.
Improve this question
Giving this code:
#include <iostream>
#include <cmath>
using namespace std;
int main() {
int k, x;
while(k > x-3) {
k--;
// cout << "x = " << x << "\n";
}
x++, k--;
int aux = abs(k-x);
cout << aux;
}
When we run it, it always pops up a constant x (x = 50) and the absolute value between the integer k and the x is always 5. Can you please explain me why and how does this works?
With the constraint of "k is greater than x", this piece of code here
while(k > x-3) {
k--;
// cout << "x = " << x << "\n";
}
Will decrease k to be 3 less than x.
The next line, x++, k++; increases them both by 1, but it doesn't change the result. k is still 3 smaller than x.
k-x is -3 and abs(k-x) is 3, hence why the program always prints 3. Assuming, of course, that both k and x are initialized and that k is bigger than x. The program as it is posted with k and x uninitialized exhibits undefined behavior, so there's no guarantee on what is going to happen. Also, as Aconcagua points out, if x is smaller than INT_MIN + 3, that also leads to undefined behavior.
I really think you should try two arbitrary numbers.
For example , imagine we are using k= 10 & x=8.
Your loop will look like:
While(10>5) 10-1=9 ... and so on, until K is not greater than (X-3).
You will get k=5, and x is the same value,8.
After the while loop you decrement k, and increment x, so k=4 and x=9.
Abs(k-x) = 5.
If you want the more theoretical explanation, the loop will grant that the difference between your two variables is 3, the X will be greater than K.
As after the loop you decrement K and increment X , the diference between them will ALWAYS be 5.
Matthieu and πάντα ῥεῖ are correct: Ths is classic undefined behavior. (One rationale for making it undefined and not simply unspecified or implementation defined is that some architectures have flags for uninitialized registers and would trap.) A compiler is actually free to compile it to an empty program: Reading an uninitialized variable can result in anything — and nothing is a subset of anything. All subsequent code after the undefined behavior is "tainted" by the preceding error and can be omitted. Note that different architectures and different compilers, possibly even different C standard libs (with the same compiler!) may give different results; even a different compiler flag (concerning optimization or function call conventions) may change this undefined behavior.
(The rest of this answer applies to the version of the question where the line after the loop read x++, k++; (instead of k-- as it is now).)
But you have encountered a consistent behavior, and the question is why it is consistent. The first assumption is that the compiler does not simply generate code to output "5", (which it could, legitimately) but actually "naively" generates machine code that corresponds to the C statements. We'll reason along the statements.
Then the behavior indicates that the memory locations where x and k reside are containing values which make k > x -3 false right away. (Otherwise, k would be decremented until the difference is 3, not 5).
If the condition is false, the variable difference will not change; from that we can conclude that it was 5 from the start with x-k == 5. If you omit the abs(), the output should be -5.
The reason the variables have these consistent intial values may be connected to things the operating system or C runtime environment do at program startup, like initializing the standard streams. Try using printf instead of cout and see if the result changes.
Related
This question already has answers here:
Undefined behavior and sequence points
(5 answers)
Closed 4 years ago.
Whats happening x after executing the code below;
int x = 10;
x += x--;
I'm expecting result 19 (adding x to x and then decrease x by 1) but result 20. How does it works behind the curtains? Thank your for your answers.
The behavior in this case was undefined before C++17, see e.g., https://en.cppreference.com/w/cpp/language/eval_order#Undefined_behavior , so if your compiler does not conform to it, it is no use testing or trying to understand it: it will depend on implementation, or even version of the compiler.
If your compiler conforms to C++17, it is guaranteed that in a simple or compound assignment (= or e.g. +=, respectively) all of the side effects of right hand side will be dealt with before evaluating the left hand side.
In your case, x-- is evaluated to be 10 accompanied by setting x=9 as its side effect, then the computer will add 10 to x=9 resulting in x=19.
Thanks to Michał for his correction, which I incorporated into the answer.
Having an older c++ might probably not do the job as the behaviour is literally defined to be undefined, by the older standard. (Thanks to #LightnessRacesinOrbit)
If you just try out an online compiler which will have the latest version, it works just fine and the result is 19 as you expected (x+=x-- is the same as x= x+x--. This means for getting the new "x", it has to sum the old "x"+the old "x" -1. So it will do x+(x--), which is x=10+(9).
Try it out here:
with:
#include <iostream>
using namespace std;
int main()
{
int x = 10;
x += x--;
cout<<x<<endl;
}
so i had this segment of code in my C++ test today:
for(int i=10;i++;i<15){cout<<i;}
what is this supposed to output? and why ?
Thanks!
A for loop will run until either:
its 2nd argument evaluates as 0/false.
the loop body calls break or return, or throws an exception, or otherwise exits the calling thread.
The code you have shown may or may not loop indefinitely. However, it will not loop the 5 times you might be expected, because the 2nd and 3rd arguments of the for statement are reversed.
The loop should look like this:
for(int i = 10; i < 15; i++)
However, in the form you have shown:
for(int i = 10; i++; i < 15)
The loop will continue running as long as i is not 0. Depending on how the compiler interprets i++ as a loop condition, it may recognize that this will lead to overflow and just decide to ignore i and make the loop run indefinitely, or it may actually increment i and let overflow happen.
In the latter case, on every loop iteration, i will be incremented, and eventually i will overflow past the maximum value that an int can hold. At that time, i will usually wrap around to a negative value, since int is a signed type (though overflow behavior is not officially defined by the C++ standard, so the wrap is not guaranteed). Then the loop will keep running since i is not 0, incrementing i each time until it eventually reaches 0, thus breaking the loop.
In either case, the loop will end up calling cout << i many thousands/millions of times (depending on the byte size of int), or call it forever until the program is terminated.
what is this supposed to output? and why ?
That unconditionally do an signed int overflow.
So it is is Undefined behavior and can do anything.
For practical purposes, with any modern compiler this loop will continue forever. The reason for that is that the code is syntactically correct (however very incorrect semantically).
for(int i = 10; i++; i < 15)
means: start with i equal to 10. Check if i++ is true (which it will be, since integers are convertible to booleans, with non-0 values converted to true). Proceed with loop body, on every iteration performing comparison of i and 15 (just comparing, not checking the result, this is your increment expression), incrementing i and checking if it is non-0.
Since compilers understand that signed integers never overflow, i++ could never go to 0 when started with 10. As a result, optimizing compiler will remove the check altogether, and turn it into infinite loop.
Last, but not the least, learn to love compiler warnings. In particular, this code produces following:
<source>:4:29: warning: for increment expression has no effect [-Wunused-value]
for (int i = 10; i++; i < 15) {
~~^~~~
<source>:4:23: warning: iteration 2147483637 invokes undefined behavior [-Waggressive-loop-optimizations]
for (int i = 10; i++; i < 15) {
~^~
<source>:4:23: note: within this loop
for (int i = 10; i++; i < 15) {
^~
The following code
int x;
cin >> x;
int b[x];
b[5] = 8;
cout << sizeof(b)/sizeof(b[0]) << endl << b[5];
with x inputted as 10 gives the ouput:
10
8
which seems very weird to me because:
According to http://www.cplusplus.com/doc/tutorial/arrays/ we shouldn't even be able to initialize an array using a value obtained from cin stream.
NOTE: The elements field within square brackets [], representing the number of elements in the array, must be a constant expression, since arrays are blocks of static memory whose size must be determined at compile time, before the program runs.
But that's not the whole story! The same code with x inputted as 4 sometimes gives the output
Segmentation fault. Core dumped.
and sometimes gives the output:
4
8
What the heck is going on? Why doesn't the compiler act in a single manner? Why can I assign a value to an array index that is larger than the array? And why can we even initialize an array using variable in the first place?
I initially mentioned this as a comment, but seeing how no one has answered, I'm gonna add it here.
What you have demonstrated above is undefined behavior. It means that you can't tell what will the outcome be. As Brian adds in the comments, it will result in a diagnostic message (which could be a warning). Since the compiler would go ahead anyway, it can be called UB as it is not defined in the standard.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Code 1
int A, B, MAX;
cout << "Give two numbers:" << endl;
cin >> A >> B;
if (A > B)
{
MAX = A;
}
else
{
MAX = B;
}
cout << "Largest amongst given numbers is: ";
cout << MAX << endl;
return 0;
Code 2
int A, B, MAX;
cout << "Give two numbers:" << endl;
cin >> A >> B;
MAX = A;
if (B > MAX)
{
MAX = B;
}
cout << "Largest amongst given numbers is: ";
cout << MAX << endl;
return 0;
In above program logic, which one is best and why? is there any difference between them.? it is my exam question i would like to ask stack overflow to know best opinion.
MAX = std::max(A, B);
Is better than both in terms of clarity.
In terms of speed, the compiler should be able to optimise any of these methods to be equivalent; but again I'd favour std::max because I'd sooner trust the compiler to optimise a standard function than some arbitrary made up code to perform the same task.
They are the same so I would prefer code 1 because it's more readable. In both cases you have to bring both A and B into a register (regardless) and then do a single comparison (regardless). And it won't write out to the variable MAX until after this segment is done (because it won't need to kick anything out of a register).
This isn't something that is going to cause any kind of performance gain. In fact, it's possible (although I doubt it) that the compiler would compile them the same (the compiler does all kinds of code modification to create an optimal set of instructions).
As suggested the only thing that likely would give a performance gain is using the library function std::max. This is because the compiler will basically perform the comparison in the most efficient way (likely without even calling a conditional jump). If your two values are integers, then you can see here that it's possible to find the max with five integer operations (all of which, except the multiplication can generally be done in a single cycle). You generally want to avoid conditional jumps as much as possible and this algorithm does that. Most likely the max function does something like this or similar (but it would have to be different for floating point values).
After MAX = std::max(A,B), the next best code is:
MAX = A > B ? A : B;
If you don't want to use that, then I prefer your "code 1" because:
code 2 always sets MAX = A, which is momentarily misleading and only becomes clear as the later code is studied; while this issue is common in C++ and many other languages, there's no particular reason to embrace that complication when it's easily avoided
for some types (the question didn't originally specify int), an assignment may be an expensive operation (e.g. copying a lot of data), so always assigning once is better than potentially assigning twice
For both those reasons, it also desirable to declare and define MAX in one step. It may not be practical if say it's a non-const reference accepted as a function argument, but when it is possible it's another good reason to prefer std::max or the ternary ? approach: you won't need a misleading and potentially inefficient or unavailable default construction. (Now you've changed the question to be int specific, the expense of copying and construction is known and trivial, and the optimiser can be counted on to remove them in most cases).
I would say use code 2. It is better because you explicitly say that if MAX B is greater than MAX A, then change MAX to B. In the other one, you don't have any defining factors about why MAX A is greater than MAX B. From what I see, you will probably have a harder time using code 1 than code 2.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Potential Problem in “Swapping values of two variables without using a third variable”
I recently read in a community that we can easily swap two numbers without using third using a XOR trick.
m^=n^=m^=n; trick was mentioned.
What do you guys think? Is this trick always useful?
the way you have written it, it is undefined behavior. This is because you are modifying a variable more than once in the same sequence point. However if you rewrite it as follows:
m ^= n;
n ^= m;
m ^= n;
then it is safe. However, "useful" is another question, it is rarely "useful" and sometimes it is actually slower than actually using a temp!
Also you need to be careful with aliasing (pointers/references) because if you try to swap something with itself, then you end up accidentally zeroing your value. For example:
#define SWAP(m, n) { m ^= n; n ^= m; m ^= n; }
int x[] = { 1, 2, 3, 4 };
int i = 0;
int j = 0;
SWAP(x[i], x[j]); // whoops, x[0] == 0 now, not 1!
a more traditional swap implementation doesn't have this issue.
No, it is undefined behaviour in both C and C++. It may work sometimes, but you should not rely on it.
Also even the "fixed" variation doesn't always work:
m ^= n;
n ^= m;
m ^= n;
This fails if m and n are references to the same variable. In this case it sets the value to zero.
C doesn't have references but even in C there are still dangers lurking if you try to use this trick:
You may try to put the "working" version into a macro SWAP, but that can fail if called with SWAP(x, x), setting x always to zero.
You may try to extend the trick to swapping two values in an array, but again this can fail if you use the same index:
a[m] ^= a[n];
a[n] ^= a[m];
a[m] ^= a[n];
Now if m == n again the value of a[m] is set to zero.
Please don't use "clever" tricks like this. Use a temporary variable to swap two values.
with that trick, you save an extra memory location to save a temporary value.
It may be efficiant for integers, but is that readable ? Your last generation optimizer may do the same.
It's often more of a danger (in your case it's actually undefined behavior; plus if one number is zero, things go wrong). Unless you're cripplingly low on memory, it's better to just use a temp variable (or the stl swap function). This is more clear about what you're doing and easier to maintain.