 |
|
 |
int a = 5, b = 6;
a = a+b;
b = a-b;
a = a-b;
Three lines.
But reliable.
No temporary variable used.
Nibu thomas.
|
|
|
|
 |
|
 |
not always applicable, because of data types range...
consider this :
char a = 200, b = 250;
a = a + b; b = a - b; a = a - b:
TOXCCT >>> GEII power [toxcct][VisualCalc 2.24][3.0 soon...]
|
|
|
|
 |
|
 |
toxcct wrote: char a = 200, b = 250;
That's why I used an int
Nibu thomas
Software Developer
|
|
|
|
 |
|
 |
char was an example to give not too high numbers... but the problem remains the same, man !!!
even a 64 bits int have a maximum value !
TOXCCT >>> GEII power [toxcct][VisualCalc 2.24][3.0 soon...]
|
|
|
|
 |
|
 |
toxcct wrote: char was an example to give not too high numbers... but the problem remains the same, man !!!
True, but then I was conscious not to make the mistake.
toxcct wrote: even a 64 bits int have a maximum value !
Sooo True.
Nibu thomas
Software Developer
|
|
|
|
 |
|
|
 |
|
 |
toxcct wrote: but you cannot always know what is inside a variable...
Well then we will never be able to add two variables...
Nibu thomas
Software Developer
|
|
|
|
 |
|
 |
that's why there's a MAX_INT constant in the limits.h header, and that's also why we usually use a temporary variable...
TOXCCT >>> GEII power [toxcct][VisualCalc 2.24][3.0 soon...]
|
|
|
|
 |
|
 |
True
Nibu thomas
Software Developer
|
|
|
|
 |
|
 |
This is an old trick known as xor swap, but to do it in one line as first mentioned would be somewhat left in the hands of the compiler. Hope this is of some help to people playing with this code.
-
SRCDOC!
|
|
|
|
 |
|
 |
Remember the following "rules":
(1) associativity of ^, i.e. (a^b)^c = a^(b^c) for a, b, c \in {0, 1}
(2) commutativity of ^, i.e. a^b = b^a for a, b \in {0, 1}
(3) a^0 = 0^a = a for a \in {0, 1}
(4) a^a = 0 for a \in {0, 1}
Choosing x, y \in {0, 1} and setting
a := x^y (first new value for x)
b := y^a (first new value for y)
c := a^b (second new value for x)
we have to show that b equals x and c equals y:
b = y^a = a^y = (x^y)^y = x^(y^y) = x^0 = x
c = a^b = b^a = (y^a)^a = y^(a^a) = y^0 = y
So the values of any two bits x, y are swapped. Since ^ acts bitwise the result holds
for any two arbitrary integers
|
|
|
|
 |
|
 |
Thank you very much. Danke sehr. Obrigado...
Finally moved to Brazil
|
|
|
|
 |
|
 |
This old XOR trick is quite common and used by all, or at least most, assembly coders, that didn't want to spoil another register. But in programming languages you have so many variables to use, that there is no need to bother with all those math tricks, unless you are dealing with images or still writing assembly code.
...Plug & Pray...
|
|
|
|
 |
|
 |
You dont need this trick in assembly language, assembly has
swap instruction to do that
The World is getting smaller and so are the people.
|
|
|
|
 |
|
 |
Sorry, I didn't mention I had in mind when writing this the old Z80 cpu.
I had written many applications on my Amstrad CPC 6128 entirely in Z80A asm, and the most common trick to exchange register variables was this one. No XCHG command or similar supported. You could do the push-pop trick but was more time consuming.
...Plug & Pray...
|
|
|
|
 |
|
 |
Yeah i latter realized that that may be case, i have done most of my assembly coding in 8086 based machines.
The World is getting smaller and so are the people.
|
|
|
|
 |
|
 |
x ^= y ^= x ^= y produces undefined behavior according to the C spec, and writing undefined code is irresponsible.
The order of evaluation doesn't matter. Precedence and associativity are irrelevant. It doesn't matter if we write it as x ^= (y ^= (x ^= y)).
The facts remain:
1. There are no sequence points in the above expression.
2. The above expression modifies the same objects multiple times.
3. The result of modifying an object multiple times between sequence points is undefined, as stated by the C specification.
Therefore we can conclude that x ^= y ^= x ^= y produces undefined behavior.
Someone compared it to:
a = b = c = 5
This is not a valid comparison; because a, b, and c are each modified only once, a = b = c = 5 indeed is well-defined.
If you don't believe
me, ask anyone on comp.lang.c (for example, see this thread.)
|
|
|
|
 |
|
 |
stickboy wrote:
x ^= y ^= x ^= y produces undefined behavior according to the C spec, and writing undefined code is irresponsible.
Hmm, I never tried to compile something like this with "C spec" but with the Microsoft C/C++ Compiler v12.00.8804 (VC6/SP5) I can tell you that its not undefined behaviour
You can ride on your "C specification" as long as you want, if it works with just one single compiler, someone will use it. And dont tell me its not portable, 99% of all windows code is not portable, and thats what this site is about - source code for Windows.
But thanks for taking the time to make your points.
Off to Brazil in a few days
|
|
|
|
 |
|
 |
Perhaps you have undefined behavior confused with implementation-defined or unspecified behavior.
Just because your compiler appears to do what you think is correct does not make it any more defined, not even for your specific compiler for your specific platform. You aren't guaranteed that other compilers for Windows will produce the same result; you aren't guaranteed that future versions of the Microsoft compiler will produce the same result; you aren't guaranteed that your current version of the Microsoft compiler will produce the same result on Mondays as it does on Tuesdays. You have no guarantees at all.
"Undefined behavior" means that a compiler is free to do anything. It can choose to do what you expect 99% of the time and can generate code to format your hard drive in the other 1%. It can make the sky fall and can make pigs fly.
Even if you choose to ignore these issues, it's irresponsible to promote use of an undefined construct, and it's especially bad to claim it's legal.
As Moak said below, you have a perfectly legal alternative that's almost as succinct: x ^= y, y ^= x, x ^= y. Why don't you use that instead?
|
|
|
|
 |
|
 |
stickboy wrote:
"Undefined behavior" means that a compiler is free to do anything.
Depending on the brand and version of the compiler, I've got the impression that they are free to do anything whenever they want.
But I am really tired of making people like you understand the issue of this article, which is explained in the first sentence.
I wonder if you check the Standards Documentation for every line of code you write for correct behaviour. The world would be a better place and programs would be error free.
Off to Brazil in a few days
|
|
|
|
 |
|
 |
SaurweinAndreas wrote:
I wonder if you check the Standards Documentation for every line of code you write for correct behaviour.
No, I don't, but if someone tells me that I've accidentally invoked undefined behavior, I correct it.
SaurweinAndreas wrote:
But I am really tired of making people like you understand the issue of this article
If you truly want to reduce the number of responses to your code snippet, you should make it legal code.
|
|
|
|
 |
|
 |
You know, I held a speech at university just the other day on Pitfalls of Programming Languages. Guess what, Multiple assignments between sequence points was one of the topics I dealt with at length. To tell you the truth, it was a frightening experience that none of the attendants, all of which self-acclaimed programmers, could define any of the terms unspecified behaviour, undefined behaviour, or implementation defined behaviour. The arguments in the following discussion were primarily based on empirical data. The peculiar "It has always worked for me, so why bother?" surfaced so many times that I was left wondering whether I accidentally held the speech in this foreign language I acquired when I was abducted by aliens Thursday night 2 weeks ago. That's a different story, though....
Anyway, if your claims, which just happen to be facts, still cannot convince the original author to reconsider, let me assure you that you have reinstated a bit of hope in me that some, however few, programmers out there are aware of the responsibilities they have as software developers and do care about them. Thanks.
|
|
|
|
 |
|
|
 |
|
 |
It's about as undefined as 1/0 (division by zero error is a joke, it's infinity).
x^=y^=x^=y can be translated by a person into discrete operations, so why not also
by a machine?
x^=y^=x^=y;
becomes (transposed because things happen right to left like: a = b = c = 1; ):
x^=y; y^=x; x^=y;
which is close to:
mov eax, x
mov ebx, y
xor eax, ebx
xor ebx, eax
xor eax, ebx
which is (when x=5 and y=1):
eax = 5
ebx = 1
eax = 4
ebx = 5
eax = 1
this code works for most variables, just replace the x with the dword ptr (ebp - 4 * &x) equivalent. Hope this helps people understand these kinds of "tools".
In the interest of code readability, and NOT trying to confuse everyone,
x^=y; y^=x; x^=y;
might be a better way of writing these kinds of statements.
|
|
|
|
 |
|
 |
BSCE2006 wrote: It's about as undefined as 1/0 (division by zero error is a joke, it's infinity).
I'd just like to point out that 1/0 is NOT infinity. For starters:
1: Infinity is a concept, not a number
2: If infinity WAS a number, using basic math rules, if 1/0=infinity, therefore 0*infinity=1, which is blatently false.
3: Whats more, not only is 1/0 undefined, the result or lack therof doesn't matter
4: If you want more proofs, I CAN find them, just cant recall the web address of an excellent essay about 'zero' and dividing by zero.
anyway, thats my 2 cents
|
|
|
|
 |