Explain the following C++ Code snippet - c++

I am new to C++ and have programming knowledge only in Java. Can anyone please explain the meaning of the code below:
#define DEF 134 ;
int k;
char msk;
PMSK *pm; //At the begining of class some declaration
// i is some counter(int)
if ( (nVersion >= 2004) && (nVersion < 2008))
{
k = to_bits(DEF, &msk);
if ( pm->orbits[k] & msk ) // for version >= 2004
{
x = atoi( grprs[i] );
if ( !defpair( i, x ) )
pm->orbits[k] &= 0xFF ^ msk; // turn off bit
}
}
to_bits() is method which will return an integer value and a (char) msk value (example 1000). It has bit operations involved in it.
What is pm->orbits[k]? Can we replace it in Java like pm.orbits[k]?
Also, what exactly the last line of code doing?

What is pm->orbits[k]? can we replace it in java like pm.orbits[k]?
Basically, yes. The -> operator de-references and then access a field (also known as access the field/function of the object pointed to by the pointer). However, if you had a reference type to begin with, you get the de-referencing "for free".
PMSK *pm1; // assume this has been initialized to point to something valid
PMSK &pm2; // assume this is a valid reference
PMSK pm3; // assume this is a valid declaration
pm1->orbits[0]; // accesses field orbits[0] of object pointed to by pm1
(*pm1).orbits[0]; // equivalent to above statement
pm2.orbits[0]; // it's implicitly understood that de-referencing should take place
pm3.orbits[0]; // no need to dereference
Dissecting the last line of code:
pm->orbits[k] &= 0xFF ^ msk; // turn off bit
^ is the bitwise exclusive or operator (a.k.a. xor). Basically it returns a bit value of 1 if both bits are not equal and 0 otherwise.
&= is the bitwise-and assigment operator. Equivalent to the following:
pm->orbits[k] = pm->orbits[k] & (0xFF^msk);
The bitwise and operator matches up equivalent bits and determines if both are 1. If they are, the result is 1. Otherwise, it's 0. So 100001 & 100100 = 100000 (binary numbers).
So it takes whatever's in msk, toggles the lowest 8 bits (1 -> 0 and 0 -> 1), then bitwise-ands that with the current pm->orbits[k] field. Finally, it assigns the result back to pm->orbits[k]
In Java, it's required to have an explicit check to somehow convert the results from a number to a boolean. However, in C++ it's implicitly understood that anything which isn't 0 is true.
if(1) // same as if(1!=0)
if(2) // same as if(2!=0)
if(0) // same as if(0!=0)
if(-1) // same as if(-1!=0)

Yes you can replace the code you mention. The '->' operator dereferences a pointer to a PMSK object. Java doesn't have pointers, only references, but they are used in the same way.
The last line is clearing the bits set in msk, however it's normally done like this:
pm->orbits[k] &= ~msk;
If you want to set the bits in msk, you'd use:
pm->orbits[k] |= msk;
Also, the following line will need to evaluate to a boolean expression, where as in C++ it just needs to be non-zero:
if ((pm->orbits[k] & msk) != 0)
{
...
}

What is pm->orbits[k]? can we replace
it in java like pm.orbits[k]?
Yes, pm is a pointer, and the -> notation is how to access members on a pointer.
The last line is a bitwise operation, called an exclusive or, the ^ operator is the same and does the same thing in Java.

The -> operator dereferences a pointer to select a field.
The last line of code does a bitwise exclusive or (XOR) of the msk value with 0xFF. This value is then bitwise ANDed with the pm->orbits array value at index k.
A few subjects that are going to help as you learn C++ and work with this code
Pointers in general
http://www.cplusplus.com/doc/tutorial/pointers/
C++ for Java Programmers ht
Bitwise operations in general http://vipan.com/htdocs/bitwisehelp.html
Arrays in C++
Passing by reference and value
Just about any introductory C++ text will have this info.

Related

Understanding bitwise XOR (^) with boolean variables

I'm from a game programming background and I've just come across a bitwise XOR ^. I've seen examples of how it works with integers, but I'm a bit confused about the result with boolean values. I know a bool is either 0 or 1, but after testing I haven't been able to replicate the ^ result with simple operators. Could someone please explain to me what the following code snippet (specifically the ^) is doing? Many thanks.
bool body1awake = rigidbody1.isAwake;
bool body2awake = rigidbody2.isAwake;
if (body1awake ^ body2awake)
{
if (body1awake) rigidbody2.SetAwake();
else rigidbody1.SetAwake();
}
Exclusive or of two bits is true when only one of them is set. If both are set or not set then it is false. Since bool basically represents a single bit (0 or 1 are its only values)
if (body1awake ^ body2awake)
means that the condition will be true on when body1awake != body2awake.
As bool is a narrower type than an int, both arguments are implicitly converted to an int prior to the XOR being evaluated. true assumes the value 1, and false assumes the value 0.
If that result is non-zero then the if body runs, and that happens if and only if body1awake is not equal to body2awake.
So perhaps the equivalent
if (body1awake != body2awake)
would have been better. If the author thinks their way is faster then they need a stern talking to with compiler optimisations and as-if rule being introduced into the conversation.

What is the purpose of the bitwise inclusive OR operator?

From what I understand, the bitwise inclusive OR operator compares every bit in the first and second operand and returns 1 if either bit is 1. Bjarne Stroustrup uses it like this (ist being an istream object):
ist.exceptions(ist.exceptions()|ios_base::bad_bit);
I haven't really worked with bits a lot in programming, should it be on my to-do list to learn? I understand that if I had an int and the value was 9, the binary would be 00001001, but that is pretty much it. I do not understand why he would use this operator in the context that he used it in.
In this case, it simply means "turn a bit on".
Just an example: I have a byte 0100 0011 serves as 8 booleans. I want to turn on 4th bit (i.e. make 4th boolean true)
By bitwise operation, it looks like this: [0100 0011] Bitwise-OR [0000 1000] and it will give you 0100 1011. Which means, it simply change 4th bit to true, regardless of its original value
You can think of it as a way to add an option to a set of existing options. An analogy would be if you're familiar with linux:
PATH = "$PATH:/somenewpath"
This says 'I want the existing path and this new path /somenewpath'
In this case he's saying 'I want the existing options in exceptions and I want the bad_bit option as well'
The std::ios::exceptions is a function which gets/sets an exception mask in the file which is used by the file object to decide in which situations it should throw an exception or not.
There exist two implementations of this function:
iostate exceptions() const; // get current bit mask
void exceptions (iostate except); // set new bit mask
The statement you've posted sets the new exception mask to the file object using ios_base::badbit flag combined with the current flags, that are currently set in the file object.
The OR bitwise operator is often used in order to create create a bitfield using already existing bitfield and a new flag. It could also be used in order to combine two flags together into a new bitfield.
Here is an example with explanation:
// Enums are usually used in order to represent
// the bitfields flags, but you can just use the
// constant integer values.
// std::ios::bad_bit is, actually, just a constant integer.
enum Flags {
A,
B,
C
};
// This function is similar to std::ios::exceptions
// in the sense that it returns a bitfield (integer,
// in which bits are manipulated directly).
Something foo() {
// Return a bitfield in which A and B flags
// are "on".
return A | B;
}
int main() {
// The actual bitfield, which is represented as a 32-bit integer
int bf = 0;
// This is what you've seen (well, somethng similar).
// So, we're assigning a new bitfield to the variable bf.
// The new bitfield consists of the flags which are enabled
// in the bitfield which foo() returns and the C flag.
bf = foo() | C;
return 0;
}

How does the compiler implement bit field arithmetics?

When asking a question on how to do wrapped N bit signed subtraction I got the following answer:
template<int bits>
int
sub_wrap( int v, int s )
{
struct Bits { signed int r: bits; } tmp;
tmp.r = v - s;
return tmp.r;
}
That's neat and all, but how will a compiler implement this? From this question I gather that accessing bit fields is more or less the same as doing it by hand, but what about when combined with arithmetic as in this example? Would it be as fast as a good manual bit-twiddling approach?
An answer for "gcc" in the role of "a compiler" would be great if anyone wants to get specific. I've tried reading the generated assembly, but it is currently beyond me.
As written in the other question, unsigned wrapping math can be done as:
int tmp = (a - b) & 0xFFF; /* 12 bit mask. */
Writing to a (12bit) bitfield will do exactly that, signed or unsigned. The only difference is that you might get a warning message from the compiler.
For reading though, you need to do something a bit different.
For unsigned maths, it's enough to do this:
int result = tmp; /* whatever bit count, we know tmp contains nothing else. */
or
int result = tmp & 0xFFF; /* 12bit, again, if we have other junk in tmp. */
For signed maths, the extra magic is the sign-extend:
int result = (tmp << (32-12)) >> (32-12); /* asssuming 32bit int, and 12bit value. */
All that does is replicate the top bit of the bitfield (bit 11) across the wider int.
This is exactly what the compiler does for bitfields. Whether you code them by hand or as bitfields is up to you, but just make sure you get the magic numbers right.
(I have not read the standard, but I suspect that relying on bitfields to do the right thing on overflow might not be safe?)
The compiler has knowledge about the size and exact position of r in your example. Suppose it is like
[xxxxrrrr]
Then
tmp.r = X;
could e.g. be expanded to (the b-suffix indicating binary literals, & is bitwise and, | is bitwise or)
tmp = (tmp & 11110000b) // <-- get the remainder which is not tmp.r
| (X & 00001111b); // <-- put X into tmp.r and filter away unwanted bits
Imagine your layout is
[xxrrrrxx] // 4 bits, 2 left-shifts
the expansion could be
tmp = (tmp & 11000011b) // <-- get the remainder which is not tmp.r
| ((X<<2) & 00111100b); // <-- filter 4 relevant bits, then shift left 2
How X actually looks like, whether a complex formulation or just a literal, is actually irrelevant.
If your architecture does not support such bitwise operations, there are still multiplications and divisions by power of two to simulate shifting, and probably these can also be used to filter out unwanted bits.

Why is there no ^^ operator in C/C++?

& has &&. | has ||. Why doesn't ^ have ^^?
I understand that it wouldn't be short-circuiting, but it would have different semantics. In C, true is really any non-zero value. Bitwise XOR is not always the same thing as logical XOR:
int a=strcmp(str1,str2);// evaluates to 1, which is "true"
int b=strcmp(str1,str3);// evaluates to 2, which is also "true"
int c=a ^^ b; // this would be false, since true ^ true = false
int d=a ^ b; //oops, this is true again, it is 3 (^ is bitwise)
Since you can't always rely on a true value being 1 or -1, wouldn't a ^^ operator be very helpful? I often have to do strange things like this:
if(!!a ^ !!b) // looks strange
Dennis Ritchie answers
There are both historical and practical reasons why there is no ^^ operator.
The practical is: there's not much use for the operator. The main point of && and || is to take advantage of their short-circuit evaluation not only for efficiency reasons, but more often for expressiveness and correctness.
[...]
By contrast, an ^^ operator would always force evaluation of both arms of the expression, so there's no efficiency gain. Furthermore, situations in which ^^ is really called for are pretty rare, though examples can be created. These situations get rarer and stranger as you stack up the operator--
if (cond1() ^^ cond2() ^^ cond3() ^^ ...) ...
does the consequent exactly when an odd number of the condx()s are true. By contrast, the && and || analogs remain fairly plausible and useful.
Technically, one already exists:
a != b
since this will evaluate to true if the truth value of the operands differ.
Edit:
Volte's comment:
(!a) != (!b)
is correct because my answer above does not work for int types. I will delete mine if he adds his answer.
Edit again:
Maybe I'm forgetting something from C++, but the more I think about this, the more I wonder why you would ever write if (1 ^ 2) in the first place. The purpose for ^ is to exclusive-or two numbers together (which evaluates to another number), not convert them to boolean values and compare their truth values.
This seems like it would be an odd assumption for a language designer to make.
For non-bool operands, I guess what you would want is for a ^^ b to be evaluated as:
(a != 0) ^ (b != 0)
Well, you have the above option and you have a few options listed in other answers.
The operator ^^ would be redundant for bool operands. Talking only about boolean operands, for the sake of argument, let's pretend that ^ was bitwise-only and that ^^ existed as a logical XOR. You then have these choices:
& - Bitwise AND -- always evaluates both operands
&& - Logical AND -- does not always evaluate both operands
| - Bitwise OR -- always evaluates both operands
|| - Logical OR -- does not always evaluate both operands
^ - Bitwise XOR -- must always evaluate both operands
^^ - Logical XOR -- must always evaluate both operands
Why didn't they create ^^ to essentially convert numerical values into bools and then act as ^? That's a good question. Perhaps because it's more potentially confusing than && and ||, perhaps because you can easily construct the equivalent of ^^ with other operators.
I can't say what was in the heads of Kernighan and Ritchie when they invented C, but you made a brief reference to "wouldn't be short-circuiting", and I'm guessing that's the reason: It's not possible to implement it consistently. You can't short-circuit XOR like you can AND and OR, so ^^ could not fully parallel && and ||. So the authors might well have decided that making an operation that sort of kind of looks like its parallel to the others but isn't quite would be worse than not having it at all.
Personally, the main reason I use && and || is for the short-circuit rather than the non-bitwise. Actually I very rarely use the bitwise operators at all.
Another workaround to the ones posted above (even if it requires another branch in the code) would be:
if ( (a? !b : b ) )
that is equivalent to xor.
In Java the ^ operator indeed does do logical XOR when used on two boolean operands (just like & and | in Java do non-short-circuiting logical AND and OR, respectively, when applied to booleans). The main difference with C / C++ is that C / C++ allows you to mix integers and booleans, whereas Java doesn't.
But I think it's bad practice to use integers as booleans anyway. If you want to do logical operations, you should stick to either bool values, or integers that are either 0 or 1. Then ^ works fine as logical XOR.
An analogous question would be to ask, how would you do non-short-circuiting logical AND and OR in C / C++? The usual answer is to use the & and | operators respectively. But again, this depends on the values being bool or either 0 or 1. If you allow any integer values, then this does not work either.
Regardless of the case for or against ^^ as an operator, you example with strcmp() sucks. It does not return a truth value (true or false), it returns a relation between its inputs, encoded as an integer.
Sure, any integer can be interpreted as a truth value in C, in which case 0 is "false" and all other values are "true", but that is the opposite of what strcmp() returns.
Your example should begin:
int a = strcmp(str1, str2) == 0; // evaluates to 0, which is "false"
int b = strcmp(str1, str3) == 0; // evaluates to 0, which is also "false"
You must compare the return value with 0 to convert it to a proper boolean value indicating if the strings were equal or not.
With "proper" booleans, represented canonically as 0 or 1, the bitwise ^ operator works a lot better, too ...

Using bitwise operators for Booleans in C++

Is there any reason not to use the bitwise operators &, |, and ^ for "bool" values in C++?
I sometimes run into situations where I want exactly one of two conditions to be true (XOR), so I just throw the ^ operator into a conditional expression. I also sometimes want all parts of a condition to be evaluated whether the result is true or not (rather than short-circuiting), so I use & and |. I also need to accumulate Boolean values sometimes, and &= and |= can be quite useful.
I've gotten a few raised eyebrows when doing this, but the code is still meaningful and cleaner than it would be otherwise. Is there any reason NOT to use these for bools? Are there any modern compilers that give bad results for this?
|| and && are boolean operators and the built-in ones are guaranteed to return either true or false. Nothing else.
|, & and ^ are bitwise operators. When the domain of numbers you operate on is just 1 and 0, then they are exactly the same, but in cases where your booleans are not strictly 1 and 0 – as is the case with the C language – you may end up with some behavior you didn't want. For instance:
BOOL two = 2;
BOOL one = 1;
BOOL and = two & one; //and = 0
BOOL cand = two && one; //cand = 1
In C++, however, the bool type is guaranteed to be only either a true or a false (which convert implicitly to respectively 1 and 0), so it's less of a worry from this stance, but the fact that people aren't used to seeing such things in code makes a good argument for not doing it. Just say b = b && x and be done with it.
Two main reasons. In short, consider carefully; there could be a good reason for it, but if there is be VERY explicit in your comments because it can be brittle and, as you say yourself, people aren't generally used to seeing code like this.
Bitwise xor != Logical xor (except for 0 and 1)
Firstly, if you are operating on values other than false and true (or 0 and 1, as integers), the ^ operator can introduce behavior not equivalent to a logical xor. For example:
int one = 1;
int two = 2;
// bitwise xor
if (one ^ two)
{
// executes because expression = 3 and any non-zero integer evaluates to true
}
// logical xor; more correctly would be coded as
// if (bool(one) != bool(two))
// but spelled out to be explicit in the context of the problem
if ((one && !two) || (!one && two))
{
// does not execute b/c expression = ((true && false) || (false && true))
// which evaluates to false
}
Credit to user #Patrick for expressing this first.
Order of operations
Second, |, &, and ^, as bitwise operators, do not short-circuit. In addition, multiple bitwise operators chained together in a single statement -- even with explicit parentheses -- can be reordered by optimizing compilers, because all 3 operations are normally commutative. This is important if the order of the operations matters.
In other words
bool result = true;
result = result && a() && b();
// will not call a() if result false, will not call b() if result or a() false
will not always give the same result (or end state) as
bool result = true;
result &= (a() & b());
// a() and b() both will be called, but not necessarily in that order in an
// optimizing compiler
This is especially important because you may not control methods a() and b(), or somebody else may come along and change them later not understanding the dependency, and cause a nasty (and often release-build only) bug.
The raised eyebrows should tell you enough to stop doing it. You don't write the code for the compiler, you write it for your fellow programmers first and then for the compiler. Even if the compilers work, surprising other people is not what you want - bitwise operators are for bit operations not for bools.
I suppose you also eat apples with a fork? It works but it surprises people so it's better not to do it.
I think
a != b
is what you want
Disadvantages of the bitlevel operators.
You ask:
“Is there any reason not to use the bitwise operators &, |, and ^ for "bool" values in C++? ”
Yes, the logical operators, that is the built-in high level boolean operators !, && and ||, offer the following advantages:
Guaranteed conversion of arguments to bool, i.e. to 0 and 1 ordinal value.
Guaranteed short circuit evaluation where expression evaluation stops as soon as the final result is known.
This can be interpreted as a tree-value logic, with True, False and Indeterminate.
Readable textual equivalents not, and and or, even if I don't use them myself.
As reader Antimony notes in a comment also the bitlevel operators have alternative tokens, namely bitand, bitor, xor and compl, but in my opinion these are less readable than and, or and not.
Simply put, each such advantage of the high level operators is a disadvantage of the bitlevel operators.
In particular, since the bitwise operators lack argument conversion to 0/1 you get e.g. 1 & 2 → 0, while 1 && 2 → true. Also ^, bitwise exclusive or, can misbehave in this way. Regarded as boolean values 1 and 2 are the same, namely true, but regarded as bitpatterns they're different.
How to express logical either/or in C++.
You then provide a bit of background for the question,
“I sometimes run into situations where I want exactly one of two conditions to be true (XOR), so I just throw the ^ operator into a conditional expression.”
Well, the bitwise operators have higher precedence than the logical operators. This means in particular that in a mixed expression such as
a && b ^ c
you get the perhaps unexpected result a && (b ^ c).
Instead write just
(a && b) != c
expressing more concisely what you mean.
For the multiple argument either/or there is no C++ operator that does the job. For example, if you write a ^ b ^ c than that is not an expression that says “either a, b or c is true“. Instead it says, “An odd number of a, b and c are true“, which might be 1 of them or all 3…
To express the general either/or when a, b and c are of type bool, just write
(a + b + c) == 1
or, with non-bool arguments, convert them to bool:
(!!a + !!b + !!c) == 1
Using &= to accumulate boolean results.
You further elaborate,
“I also need to accumulate Boolean values sometimes, and &= and |=? can be quite useful.”
Well, this corresponds to checking whether respectively all or any condition is satisfied, and de Morgan’s law tells you how to go from one to the other. I.e. you only need one of them. You could in principle use *= as a &&=-operator (for as good old George Boole discovered, logical AND can very easily be expressed as multiplication), but I think that that would perplex and perhaps mislead maintainers of the code.
Consider also:
struct Bool
{
bool value;
void operator&=( bool const v ) { value = value && v; }
operator bool() const { return value; }
};
#include <iostream>
int main()
{
using namespace std;
Bool a = {true};
a &= true || false;
a &= 1234;
cout << boolalpha << a << endl;
bool b = {true};
b &= true || false;
b &= 1234;
cout << boolalpha << b << endl;
}
Output with Visual C++ 11.0 and g++ 4.7.1:
true
false
The reason for the difference in results is that the bitlevel &= does not provide a conversion to bool of its right hand side argument.
So, which of these results do you desire for your use of &=?
If the former, true, then better define an operator (e.g. as above) or named function, or use an explicit conversion of the right hand side expression, or write the update in full.
Contrary to Patrick's answer, C++ has no ^^ operator for performing a short-circuiting exclusive or. If you think about it for a second, having a ^^ operator wouldn't make sense anyway: with exclusive or, the result always depends on both operands. However, Patrick's warning about non-bool "Boolean" types holds equally well when comparing 1 & 2 to 1 && 2. One classic example of this is the Windows GetMessage() function, which returns a tri-state BOOL: nonzero, 0, or -1.
Using & instead of && and | instead of || is not an uncommon typo, so if you are deliberately doing it, it deserves a comment saying why.
Patrick made good points, and I'm not going to repeat them. However might I suggest reducing 'if' statements to readable english wherever possible by using well-named boolean vars.For example, and this is using boolean operators but you could equally use bitwise and name the bools appropriately:
bool onlyAIsTrue = (a && !b); // you could use bitwise XOR here
bool onlyBIsTrue = (b && !a); // and not need this second line
if (onlyAIsTrue || onlyBIsTrue)
{
.. stuff ..
}
You might think that using a boolean seems unnecessary, but it helps with two main things:
Your code is easier to understand because the intermediate boolean for the 'if' condition makes the intention of the condition more explicit.
If you are using non-standard or unexpected code, such as bitwise operators on boolean values, people can much more easily see why you've done this.
EDIT: You didnt explicitly say you wanted the conditionals for 'if' statements (although this seems most likely), that was my assumption. But my suggestion of an intermediate boolean value still stands.
Using bitwise operations for bool helps save unnecessary branch prediction logic by the processor, resulting from a 'cmp' instruction brought in by logical operations.
Replacing the logical with bitwise operations (where all operands are bool) generates more efficient code offering the same result. The efficiency ideally should outweigh all the short-circuit benefits that can be leveraged in the ordering using logical operations.
This can make code a bit un-readable albeit the programmer should comment it with reasons why it was done so.
IIRC, many C++ compilers will warn when attempting to cast the result of a bitwise operation as a bool. You would have to use a type cast to make the compiler happy.
Using a bitwise operation in an if expression would serve the same criticism, though perhaps not by the compiler. Any non-zero value is considered true, so something like "if (7 & 3)" will be true. This behavior may be acceptable in Perl, but C/C++ are very explicit languages. I think the Spock eyebrow is due diligence. :) I would append "== 0" or "!= 0" to make it perfectly clear what your objective was.
But anyway, it sounds like a personal preference. I would run the code through lint or similar tool and see if it also thinks it's an unwise strategy. Personally, it reads like a coding mistake.