Does this trick always work? [duplicate] - c++

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.

Related

Why is always the answer equal to 5? [closed]

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.

Should I define constants for repeating literals in the code?

I have an example code like this, in which the literal 1 repeats several times.
foo(x - 1);
y = z + 1;
bar[1] = y;
Should I define a constant ONE, and replace the literals with it?
constexpr int ONE = 1;
foo(x - ONE);
y = z + ONE;
bar[ONE] = y;
Would this replacement make any performance improvement and/or reduce machine code size in the favor of reducing code readability? Would the number of repeating of the literal change the answer?
It will not bring you any performance/memory improvements. However, you should try to keep your code clean from magical numbers. So, if there is a repeated constant in your code in several places, and in all those places this constant is the same from logical point of view, it would be better to make it a named constant.
Example:
const int numberOfParticles = 10; //This is just an example, it's better not to use global variables.
void processParticlesPair(int i, int j) {
for (int iteration = 0; iteration < 10; ++iteration) {
//note, that I didn't replace "10" in the line above, because it is not a numberOrParticles,
//but a number of iterations, so it is a different constant from a logical point of view.
//Do stuff
}
}
void displayParticles() {
for (int i = 0; i < numberOfParticles; ++i) {
for (int j = 0; j < numberOfParticles; ++j) {
if (i != j) {
processParticlesPair(i, j);
}
}
}
}
Depends. If you just have 1s in your code and you ask if you should replace them: DONT. Keep your code clean. You will not have any performance or memory advantages - even worse, you might increase build time
If the 1, however, is a build-time parameter: Yes, please introduce a constant! But choose a better name than ONE!
Should I define a constant ONE, and replace the literals with it?
No, absolutely not. If you have a name that indicates the meaning of the number (e.g. NumberOfDummyFoos), if its value can change and you want to prevent having to update it in a dozen locations, then you can use a constant for that, but a constant ONE adds absolutely no value over a literal 1.
Would this replacement make any performance improvement and/or reduce machine code size in the favor of reducing code readability?
In any realistic implementation, it does not.
Replacing literals with named constants make only sense,
if the meaning of the constant is special. Replacing 1 with ONE is
just overhead in most cases, and does not add any useful information
to the reader, especially if it is used in different functions (index, part of a calculation etc.). If the entry 1 of an array is somehow special, using a constant THE_SPECIAL_INDEX=1 would make sense.
For the compiler it usually does not make any difference.
In assembly, one constant value generally takes the same amount of memory as any other. Setting a constant value in your source code is more of a convenience for humans than an optimization.
In this case, using ONE in such a way is neither a performance or readability enhancement. That's why you've probably never seen it in source code before ;)

swap two number without using a temporary variable [duplicate]

This question already has answers here:
Swapping two variable value without using third variable
(31 answers)
Closed 9 years ago.
I found this common solution :-
int a=10, b=20;
a=a+b;
b=a-b;
a=a-b;
But what if a=2147483647 the largest value of an integer then probably a=a+b will not be feasible.
How about using the std libs? ;)
std::swap(a,b);
Although you may also use the XORing algorithm but dont use it until you really have to.
The reason is well explained here:-
On modern CPU architectures, the XOR technique is considerably slower
than using a temporary variable to do swapping. One reason is that
modern CPUs strive to execute instructions in parallel via instruction
pipelines. In the XOR technique, the inputs to each operation depend
on the results of the previous operation, so they must be executed in
strictly sequential order. If efficiency is of tremendous concern, it
is advised to test the speeds of both the XOR technique and temporary
variable swapping on the target architecture.
Although its too late but since you have not mentioned that you want build in functions or not hence the swap method is the easiest one.
However you may also try to use the XOR method(although check the above reference about its performance) like this:
a ^= b;
b ^= a;
a ^= b;
The solution is:
a ^= b;
b ^= a;
a ^= b;
It works because x ^ x equals 0 for any value of x, and thus, x ^ y ^ x (in any order) equals y for any values of x and y. It's unlikely to be faster than just using a temporary though (unless you're programming for a CPU with high register contention and no pipelining ability).
Try XORing as below.
a ^= b;
b ^= a;
a ^= b;

C++ for-loop condition

I want to know why this loops runs even when result.bad_matches.size()=0
for (int i = 1; i <= result.badmatches.size() - 1; i++)
{
...
}
Also, is there any other way I could stop it from running when badmatches size is 0 without using an if condition?
This depends on the type size() returns. It is probably a standard container and thus will be an unsigned type and those types wrap around on overflow. That means it the result of subtracting one will be the maximum value of that type.
Either use a comparison that doesn't require you to subtract from the size (<, !=) or just use iterators or a for-auto loop. Under any circumstance you should at least use the same type for iterating as the nested size_type of the container and not int.
for(auto& x : result.badmatches) {
// ...
}
use while(result.badmatches.size()) to NOT execute it.
result.badmatches.size()-1 this will be converted to -1. If its an unsigned integer, then -1 is interpreted as 0xFFFFFFFF(on a 32 bit machine). This will make the loop run for 2^32 or 2^64 times. To avoid this, use while() as before IF you're certain that result.badmatches.size() will return 0.
size must be returning an unsigned so 0-1 is getting upgraded to unsigned and so is the left value.
So for int size of 4 bytes, -1 will be represented as 2^32 -1 in unsigned int.
If you don't want this behavior then just cast it like this : static_cast <signed int > (result.badmatches.size());
PS: I've not touched C++ for past 4 years pl. excuse little mistakes.
The right way is:
for (int i=0;i< result.badmatches.size() ;++i)
{
}
If you specifically don't want this loop to enter when the sise of the collection is zero then you could check for ! badmatches.empty() assuming that badmatches is an STL container. However, if you structure your code slightly differently, you'll probably overcome this issue without having to do that:
for (size_t i=0; i < result.badmatches.size(); i++)
{
}
I've changed the int to size_t which is the same type that size() returns (an unsigned integer), changed the initial value to 0 and the comparison so that it will exit if i >= result.badmatches.size() Generally, I'd say that this is the clearest way of presenting an indexed approach as it matches the natural indexing of collections and if you need 1, 2, 3 ... rather than 0, 1, 2 in your loop, then you can address that within it.
If you're still having problems, two questions:
Is there anything in your loop that might alter the value of result.badmatches.size()?
Is your code multithreaded with a possibility that result.badmatches.size() could change by actions on another thread?
After understanding the problem explained by #Prototype Stark #Aga , i came to a more simpler solution , using which i can keep my initial index to 1 .
for(int i=1;i+1<=result.badmatches.size();i++)
Thanks for all the help , it's much clearer now .

assignment operation confusion

What is the output of the following code:
int main() {
int k = (k = 2) + (k = 3) + (k = 5);
printf("%d", k);
}
It does not give any error, why? I think it should give error because the assignment operations are on the same line as the definition of k.
What I mean is int i = i; cannot compile.
But it compiles. Why? What will be the output and why?
int i = i compiles because 3.3.1/1 (C++03) says
The point of declaration for a name is immediately after its complete declarator and before its initializer
So i is initialized with its own indeterminate value.
However the code invokes Undefined Behaviour because k is being modified more than once between two sequence points. Read this FAQ on Undefined Behaviour and Sequence Points
int i = i; first defines the variable and then assigns a value to it. In C you can read from an uninitialized variable. It's never a good idea, and some compilers will issue a warning message, but it's possible.
And in C, assignments are also expressions. The output will be "10", or it would be if you had a 'k' there, instead of an 'a'.
Wow, I got 11 too. I think k is getting assigned to 3 twice and then once to 5 for the addition. Making it just int k = (k=2)+(k=3) yields 6, and int k = (k=2)+(k=4) yields 8, while int k = (k=2)+(k=4)+(k=5) gives 13. int k = (k=2)+(k=4)+(k=5)+(k=6) gives 19 (4+4+5+6).
My guess? The addition is done left to right. The first two (k=x) expressions are added, and the result is stored in a register or on the stack. However, since it is k+k for this expression, both values being added are whatever k currently is, which is the second expression because it is evaluated after the other (overriding its assignment to k). However, after this initial add, the result is stored elsewhere, so is now safe from tampering (changing k will not affect it). Moving from left to right, each successive addition reassigns k (not affected the running sum), and adds k to the running sum.