[SOLVED] XOR and <cmath> header - Why is it included in this programming example?

x BlueRobot

Administrator
Staff member
Joined
May 7, 2013
Posts
10,400
Code:
#include <iostream>
#include <cmath>

int main() {

    bool p, q;

    p = q = true;

    std::cout << p << " XOR " << q << " is " << 
        ((p || q) && !(p && q)) << '\n';

    p = false;
    q = true;

    std::cout << p << " XOR " << q << " is " << 
        ((p || q) && !(p && q)) << "\n";

    p = true;
    q = false;

    std::cout << p << " XOR " << q << " is " <<
        ((p || q) && !(p && q)) << "\n";

    p = q = false;

    std::cout << p << " XOR " << q << " is " <<
        ((p || q) && !(p && q)) << "\n";

    std::cin.get();

    return 0;

}

Okay, since I've decided to learn C++ again, I came across this example of testing the truth table and the XOR expression. I'm confused to why the author has added the <cmath> header, which is used for maths functions and doesn't seem to have any relevance in the program.

Any ideas?
 
I am also not sure as to why it was included....

Have you tried compiling it without this present?

Also, if you're just working with booleans the bit-wise XOR(^) also works well. None of my professors seem to like it though...
 
It works perfectly fine without the header, that's one of the first things which I tried, so I'm confused to why it's added :huh:
 
Perhaps it was just a mistake to add it. Does this example come from a series? If so, a single base project may have been used for multiple code samples, some of which needed <cmath>, and the author forgot to remove it from those few that don't.
 
I'm more confused on why they didn't just do this:
Code:
[NO-PARSE]std::cout << (1 ^ 1) << std::endl;
std::cout << (1 ^ 0) << std::endl;
std::cout << (0 ^ 1) << std::endl;
std::cout << (0 ^ 0) << std::endl;[/NO-PARSE]

The header isn't necessary for this code, regardless of whether they thought it may have been needed, just left it because of its insignificance, or forgot it there.

Here's an example for you to try. :)
Code:
[plain]int x = 0;
   for (int i = 0; i < 2; i++)
   {
      for (int j = 0; j < 2; j++)
      {
         _asm
         {
            mov eax, i
            xor eax, j
            mov dword ptr[x], eax
         }
         std::cout << i << " XOR " << j << " = " << x << std::endl;
      }
   }[/plain]

Output:
Code:
[plain]0 XOR 0 = 0
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0[/plain]

Note: With GCC that looks a bit different:
Code:
int x = 0;
   for (int i = 0; i < 2; i++)
   {
      for (int j = 0; j < 2; j++)
      {
         asm volatile("xor  %%ebx,%%eax"
                             :"=a"(x)
                             :"a"(i), "b"(j)
                             );
         std::cout << i << " XOR " << j << " = " << x << std::endl;
      }
   }
 
Last edited:
The ^ operator is used later on in the book, my other C++ book explains it all together like you did. I thought the asm keyword was related to Assembly :smile9:
 
The ^ operator is used later on in the book, my other C++ book explains it all together like you did. I thought the asm keyword was related to Assembly :smile9:

It is. :) That is inline assembly in C++. It shows the differences between MSVC++ and GCC according to syntax. GCC uses AT&T syntax I believe, which I hate (go Microsoft! on this one... The syntax used by GCC is much less succinct). They both do relatively the same thing however, so I'll explain what my ASM does using the easier to read syntax:
Code:
mov eax, i
xor eax, j
mov dword ptr[x], eax

-- Move the value of i to the eax register (32 bits), xor the value in the eax register with the variable j, which stores the result in the eax register after this instruction is executed. Then we move the value embedded within that eax register off to the variable x, by a 32 bit pointer. dword = 32bits integer, and ptr stands for pointer.
 
Last edited:
The ^ operator is used later on in the book, my other C++ book explains it all together like you did. I thought the asm keyword was related to Assembly :smile9:

It is. :) That is inline assembly in C++. It shows the differences between MSVC++ and GCC according to syntax. GCC uses AT&T syntax I believe, which I hate (go Microsoft! on this one... The syntax used by GCC is much less succinct). They both do relatively the same thing however, so I'll explain what my ASM does using the easier to read syntax:
Code:
mov eax, i
xor eax, j
mov dword ptr[x], eax

-- Move the value of i to the eax register (32 bits), xor the value in the eax register with the variable j, which stores the result in the eax register after this instruction is executed. Then we move the value embedded within that eax register off to the variable x, by a 32 bit pointer. dword = 32bits integer, and ptr stands for pointer.

Why did to you choose the eax register as opposed to any other? Is it simply because it's the first general purpose 32bit register? Would ebx/ecx/edx have worked just as well?

Also, how did you know it wasn't in use at the time and you weren't about to overwrite some important data? I assume that is that the job of the compiler: to clear the eax register of all important data before the asm keyword???

Thanks.
 
Why did to you choose the eax register as opposed to any other? Is it simply because it's the first general purpose 32bit register? Would ebx/ecx/edx have worked just as well?

Also, how did you know it wasn't in use at the time and you weren't about to overwrite some important data? I assume that is that the job of the compiler: to clear the eax register of all important data before the asm keyword???

Thanks.

You could've used any other. I know it wasn't in use because instructions don't happen at the same time, but rather simultaneously, and things get pushed and popped off the stack and registers are changed sequentially, in the order essentially in which your code is written to be executed...

Code:
[NO-PARSE]int x = 10;
_asm
{
   mov ebx, 20
   mov x, ebx
}
std::cout << x << std::endl;[/NO-PARSE]

I assume that is that the job of the compiler: to clear the eax register of all important data before the asm keyword???

No, mov will not append to existing data anyways, but rather, replace the pre-existing contents of that register.
Code:
[NO-PARSE]int x = 10;
_asm
{
   mov eax, 10
   mov eax, 20
   mov eax, 30
   mov x, eax
}
std::cout << x << std::endl;[/NO-PARSE]

If you wanted to clear it out, all you'd need to do is this:
Code:
[plain]_asm xor eax, eax[/plain]

which will set eax to a value of 0.

Run this code and see what you see:
Code:
[plain]int x = 10;
_asm mov x, eax;
std::cout << x << std::endl;[/plain]

Using the _asm keyword doesn't enforce a cleanup of the register, run it a few times to verify.
 
Last edited:
When using inline asm, it more becomes YOUR job to clean up after yourself if you need to do so.

edit: Meant to edit my last post.
 
Using the mov instruction, would the other register still retain it's value? For example, let's just say that eax contains 10 and you wanted to move that value into the ebx register, would the eax register still be 10 or become 0?
 
Using the mov instruction, would the other register still retain it's value? For example, let's just say that eax contains 10 and you wanted to move that value into the ebx register, would the eax register still be 10 or become 0?

It should retain it's value. Take this code for instance:
Code:
[plain]int x = 0;
   int y = 0;
   _asm
   {
      mov eax, 10
      mov ebx, eax
      mov x, eax
      mov y, ebx
   }
   std::cout << x << std::endl;
   std::cout << y << std::endl;[/plain]
 

Has Sysnative Forums helped you? Please consider donating to help us support the site!

Back
Top