Can this C/C++ if() statement ever evaluate to TRUE? - c++

According to PC-lint, the following statement will never be TRUE:
if((variable & 0x02) == 1)
I am using a C compiler for embedded systems that evaluates it to TRUE whenever the corresponding bit in variable is set. I guess the compiler is doing a TRUE/FALSE comparison of both sides of the == instead of comparing the resulting numbers. In other words, every time the expression (varable & 0x02) is not zero (i.e. TRUE), the statement will also be TRUE, since the value 1 is also TRUE (not zero).
I don't know if the C/C++ standards clearly define how a compiler should behave in this case. Are there any C/C++ experts out there who can answer this question based on what the standards (e.g. C90, C99, etc.) say?
P.S.: In the statement above, "variable" is an unsigned char.

PC-lint is right. Assuming var is an integer variable, the expression var & 0x02 can evaluate to two values: 0 and 2. It will never be equal to 1, which is what the if statement is testing.
To expand on this, the equality operator is being applied to two integer values. What matters is whether both operands evaluate to the same number, not whether they're both simultaneously "true" or "false".
To test whether bit 1 is set, one could use:
if (variable & 0x02) {
...
}
Given that your compiler behaves the way you say it does, it's clearly non-compliant. However, it will almost certainly handle if (variable & 0x02) correctly. My recommendation would be to fix the code so it won't break silently if you were ever to change compilers.
Finally, the situation is different if: (1) the code is C++ and not C; and (2) variable is instance of a class; and (3) the class overloads the operators in question. In that case, the behaviour is down to what the overloaded operators actually do.

In C++, this can evaluate to a true value if (and only if) variable is an instance of a class with an overloaded operator& which does not conform to normal bitwise AND semantics.
In C, this condition will always be false. §6.5.10 defines the semantics of the bitwise AND operator, and it's quite simple and to the point:
4. The result of the binary & operator is the bitwise AND of the operands (that is, each bit in
the result is set if and only if each of the corresponding bits in the converted operands is
set).
It's clear that the result cannot be 1, as the 1 bit is not set in the converted value of the right-hand-side operand (namely, 0x02).
Naturally, if undefined behavior has been invoked at some point in the program's past (or at compile time!), then anything can happen. Barring this possibility, however, your compiler is non-compliant. That is to say, broken. This, unfortunately, is extremely common on odd embedded compilers. If you're lucky, you may even be able to report the bug and get it fixed.

I don't think the standard defines anything about this very specific and unusual issue. As said by aix, that statement can never be true because (in binary):
XXXX XXXX -> variable
0000 0010 -> 0x02
--------- AND
0000 00X0 -> result
(simplifying to 8-bit types)
So your only results can be 0000 0010 (which is 2) or 0000 0000 (which is 0).

For C, the answer is no.
The C standard says about & (6.5.10):
The result of the binary & operator is the bitwise AND of the operands (that is, each bit in
the result is set if and only if each of the corresponding bits in the converted operands is
set).
Since in 2 only the bit 1 is set, the value of the expression can only have set the bit 1. It can take no other values than 2 and 0. Neither 2 nor 0 can compare equal to 1.
The bit representations of integers are defined in 6.2.6.2 (for non-negative values in the usual way).

Basically, lint is right here. At least on any platform I know of, the condition will yield false. Look at the bit representation of the numbers: x & 2 (0010) will always be either zero or 2 (0010) and thus different from 1 (0001) for any integer x.

Let us consider the binary value of 2
02 = 0010 (say a 4 bit number)
and the binary value of 1 is
01 = 0001
The least significat bit of 2 is always zero that is the left most bit is 0. SO
The & (and) operation with 0 never gives 1 hence we can say it can never be equal to 1
0 0 => 0
0 1 => 0
1 1 => 1
Note: & indicates the bit wise and operation
2 - 0010
3 - 0011
0010
So the output with xx & 2 will be 0 or 2.

Related

Is it possible to differentiate between 0 and -0?

I know that the integer values 0 and -0 are essentially the same.
But, I am wondering if it is possible to differentiate between them.
For example, how do I know if a variable was assigned -0?
bool IsNegative(int num)
{
// How ?
}
int num = -0;
int additinon = 5;
num += (IsNegative(num)) ? -addition : addition;
Is the value -0 saved in the memory the exact same way as 0?
It depends on the machine you're targeting.
On a machine that uses a 2's complement representation for integers there's no difference at bit-level between 0 and -0 (they have the same representation)
If your machine used one's complement, you definitely could
0000 0000 -> signed  0 
1111 1111 -> signed −0
Obviously we're talking about using native support, x86 series processors have native support for the two's complement representation of signed numbers. Using other representations is definitely possible but would probably be less efficient and require more instructions.
(As JerryCoffin also noted: even if one's complement has been considered mostly for historical reasons, signed magnitude representations are still fairly common and do have a separate representation for negative and positive zero)
For an int (in the almost-universal "2's complement" representation) the representations of 0 and -0 are the same. (They can be different for other number representations, eg. IEEE 754 floating point.)
Let's begin with representing 0 in 2's complement (of course there exist many other systems and representations, here I'm referring this specific one), assuming 8-bit, zero is:
0000 0000
Now let's flip all the bits and add 1 to get the 2's complement:
1111 1111 (flip)
0000 0001 (add one)
---------
0000 0000
we got 0000 0000, and that's the representation of -0 as well.
But note that in 1's complement, signed 0 is 0000 0000, but -0 is 1111 1111.
I've decided to leave this answer up since C and C++ implementations are usually closely related, but in fact it doesn't defer to the C standard as I thought it did. The point remains that the C++ standard does not specify what happens for cases like these. It's also relevant that non-twos-complement representations are exceedingly rare in the real world, and that even where they do exist they often hide the difference in many cases rather than exposing it as something someone could easily expect to discover.
The behavior of negative zeros in the integer representations in which they exist is not as rigorously defined in the C++ standard as it is in the C standard. It does, however, cite the C standard (ISO/IEC 9899:1999) as a normative reference at the top level [1.2].
In the C standard [6.2.6.2], a negative zero can only be the result of bitwise operations, or operations where a negative zero is already present (for example, multiplying or dividing negative zero by a value, or adding a negative zero to zero) - applying the unary minus operator to a value of a normal zero, as in your example, is therefore guaranteed to result in a normal zero.
Even in the cases that can generate a negative zero, there is no guarantee that they will, even on a system that does support negative zero:
It is unspecified whether these cases actually generate a negative zero or a normal zero, and whether a negative zero becomes a normal zero when stored in an object.
Therefore, we can conclude: no, there is no reliable way to detect this case. Even if not for the fact that non-twos-complement representations are very uncommon in modern computer systems.
The C++ standard, for its part, makes no mention of the term "negative zero", and has very little discussion of the details of signed magnitude and one's complement representations, except to note [3.9.1 para 7] that they are allowed.
If your machine has distinct representations for -0 and +0, then memcmp will be able to distinguish them.
If padding bits are present, there might actually be multiple representations for values other than zero as well.
In the C++ language specification, there is no such int as negative zero.
The only meaning those two words have is the unary operator - applied to 0, just as three plus five is just the binary operator + applied to 3 and 5.
If there were a distinct negative zero, two's complement (the most common representation of integers types) would be an insufficient representation for C++ implementations, as there is no way to represent two forms of zero.
In contrast, floating points (following IEEE) have separate positive and negative zeroes. They can be distinguished, for example, when dividing 1 by them. Positive zero produces positive infinity; negative zero produces negative infinity.
However, if there happen to be different memory representations of the int 0 (or any int, or any other value of any other type), you can use memcmp to discover that:
#include <string>
int main() {
int a = ...
int b = ...
if (memcmp(&a, &b, sizeof(int))) {
// a and b have different representations in memory
}
}
Of course, if this did happen, outside of direct memory operations, the two values would still work in exactly the same way.
To simplify i found it easier to visualize.
Type int(_32) is stored with 32 bits. 32 bits means 2^32 = 4294967296 unique values. Thus :
unsigned int data range is 0 to 4,294,967,295
In case of negative values it depends on how they are stored. In case
Two's complement –2,147,483,648 to 2,147,483,647
One's complement –2,147,483,647 to 2,147,483,647
In case of One's complement value -0 exists.

Count the bits set in 1 for binary number in C++

How many bits are set in the number 1 in one binary number of 15 digits.
I have no idea how to start this one. Any help/hints?
Smells like homework, so I'll be all vague and cryptic. But helpful, since that's what we do here at SO.
First, let's figure out how to check the first bit. Hint: you want to set all other bits of the variable to zero, and check the value of the result. Since all other bits are zero, the value of the variable will be the value of the first bit (zero or one). More hint: to set bits to zero, use the AND operation.
Second, let's move the second bit to the first position. There's an operation in C++ just for that.
Third, rinse and repeat until done. Count them ones as you do so.
EDIT: so in pseudocode, assuming x is the source variable
CountOfOnes=0
while X != 0
Y = the first bit of X (Y becomes either 0 or 1)
CountOfOnes = CountOfOnes + Y
X = X right shift 1
Specifically for C++ implementation, you need to make X an unsigned variable; otherwise, the shift right operation will act up on you.
Oh, and << and >> operators are exactly bitwise shift. In C++, they're sometimes overridden in classes to mean something else (like I/O), but when acting on integers, they perform bit shifting.

What do the C and C++ standards say about bit-level integer representation and manipulation?

I know the C and C++ standards don't dictate a particular representation for numbers (could be two's complement, sign-and-magnitude, etc.). But I don't know the standards well enough (and couldn't find if it's stated) to know if there are any particular restrictions/guarantees/reserved representations made when working with bits. Particularly:
If all the bits in an integer type are zero, does the integer as whole represent zero?
If any bit in an integer type is one, does the integer as a whole represent non-zero? (if this is a "yes" then some representations like sign-and-magnitude would be additionally restricted)
Is there a guaranteed way to check if any bit is not set?
Is there a guaranteed way to check if any bit is set? (#3 and #4 kind of depend on #1 and #2, because I know how to set, for example the 5th bit (see #5) in some variable x, and I'd like to check a variable y to see if it's 5th bit is 1, I would like to know if if (x & y) will work (because as I understand, this relies on the value of the representation and not whether nor not that bit is actually 1 or 0))
Is there a guaranteed way to set the left-most and/or right-most bits? (At least a simpler way than taking a char c with all bits true (set by c = c | ~c) and doing c = c << (CHAR_BIT - 1) for setting the high-bit and c = c ^ (c << 1) for the low-bit, assuming I'm not making any assumptions I should't be, given these questions)
If the answer to #1 is "no" how could one iterate over the bits in an integer type and check if each one was a 1 or a 0?
I guess my overall question is: are there any restrictions/guarantees/reserved representations made by the C and C++ standards regarding bits and integers, despite the fact that an integer's representation is not mandated (and if the C and C++ standards differ in this regard, what's their difference)?
I came up with these questions while doing my homework which required me to do some bit manipulating (note these aren't questions from my homework, these are much more "abstract").
Edit: As to what I refer to as "bits," I mean "value forming" bits and am not including "padding" bits.
(1) If all the bits in an integer type are zero, does the integer as whole represent zero?
Yes, the bit pattern consisting of all zeroes always represents 0:
The representations of integral types shall define values by use of a pure binary numeration system.49 [§3.9.1/7]
49 A positional representation for integers that uses the binary digits 0 and 1, in which the values represented by successive bits are additive, begin with 1, and are multiplied by successive integral power of 2, except perhaps for the bit with the highest position.
(2) If any bit in an integer type is one, does the integer as a whole represent non-zero? (if this is a "yes" then some representations like sign-and-magnitude would be additionally restricted)
No. In fact, signed magnitude is specifically allowed:
[ Example: this International Standard permits 2’s complement, 1’s complement and signed magnitude representations for integral types. —end
example ] [§3.9.1/7]
(3) Is there a guaranteed way to check if any bit is not set?
I believe the answer to this is "no," if you consider signed types. It is equivalent to equality testing with a bit pattern of all ones, which is only possible if you have a way to produce a signed number with bit pattern of all ones. For an unsigned number this representation is guaranteed, but casting from unsigned to signed is undefined if the number is unrepresentable:
If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined. [§4.7/3]
(4) Is there a guaranteed way to check if any bit is set?
I don't think so, because signed magnitude is allowed—0 would compare equal to −0. But it should be possible with unsigned numbers.
(5) Is there a guaranteed way to set the left-most and/or right-most bits?
Again, I believe the answer is "yes" for unsigned numbers, but "no" for signed numbers. Shifts are undefined for negative signed numbers:
Otherwise, if E1 has a signed type and non-negative value, and E1 × 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined. [§5.8/2]
You use the term "all bits" repeatedly, but you do not clarify what "all bits" you are referring to. Object representation of integer types in C/C++ might include value-forming bits and padding bits. The only integer type that is guaranteed not to have padding bits is [signed/unsigned] char.
The language always guaranteed that if all value-forming bits are zero, then the represented integer value is also zero.
As for padding bits, things are/were a bit more complicated. The original specification of C language (C89/90 as well as the original C99) did not guarantee that setting all object bits to zero produced a valid integer representation. It could've produced an invalid trap representation. I.e. in the original C (and even in C99 at first) using memset(..., 0, ...) on integer types did not guarantee that the objects will receive valid zero values (with the exception of [signed/unsigned] char). This was changed in later specifications, namely in one of the technical corrigendums for C99. Now it is required that all-zero bit pattern in an integer object (that involves all bits, including padding ones) represents a valid zero value.
I.e. in modern C it is legal to use memset(..., 0, ...) to set any integer objects to zero, but it became legal only after C99.
You already got some answers about the representation of integer values. There is exactly one way that is guaranteed to give you all the individual bits of any object that is represented in memory: view it as array of unsigned char. This is the only integral type that has no padding bits and is guaranteed to have no trap representation. So casting a pointer of type T* to your object to unsigned char* will always work, as long as you only access the first sizeof(T) bytes. By that you could inspect and set all bytes (and thus bits) to your liking.
If you are interested in more details, here I have written something up about the anatomy of integer types in C. C++ might differ a bit from that, in particular type puning through union as described there doesn't seem to be well defined in C++.
Q: If any bit in an integer type is one, does the integer as a whole represent non-zero? (if this is a "yes" then some representations like sign-and-magnitude would be additionally restricted)
No. The standards for C and C++ don't rule out signed magnitude or one's complement, both of which have +0 and -0. While +0 and -0 do have to compare equal, but they do not have to have the same representation.
Good luck finding a machine nowadays that uses signed magnitude or one's complement.
If you want your brain to explode, consider this: If you interpret an int or long or long long as an array of unsigned char (which is the most reasonable thing to do if you want to see all the bits), you know that the order of bytes is not defined, for example "bigendian" vs. "littleendian". We all (hopefully) know that.
But it is worse: Each bit of an int could be stored in any of the bits of the array of char. So there are 32! ways how the bits of a 32 bit integer could be mapped to an array of four 8-bit unsigned chars by a truly bizarre implementation. Fortunately, I haven't encountered more than two ways myself (and I know of one more ordering in a real computer).
If all the bits in an integer type are zero, does the integer as whole represent zero?
Edit: since you have now clarified that you are not concerned with the padding bits, the answer to this is actually "yes". But I leave the original:
Not necessarily, it could be a trap representation. See C99 6.2.6.1:
For unsigned integer types other than unsigned char, the bits of the object
representation shall be divided into two groups: value bits and padding bits (there need not be any of the latter)
The presence of padding bits allows for the possibility that all 0 is a trap representation. (As noted by Keith Thompson in the comment below, the more recent C11 makes explicit that such a representation is not a trap representation).
and
The values of any padding bits are unspecified
and
44) Some combinations of padding bits might generate trap representations
If you restrict the question to value and sign bits, the answer is yes, due to 6.2.6.2:
If there are N value bits, each bit shall represent a different
power of 2 between 1 and 2 N −1 , so that objects of that type shall be capable of representing values from 0 to 2 N − 1 using a pure binary representation; this shall be known as the value representation.
and
If the sign bit is zero, it shall not affect the resulting value.
If any bit in an integer type is one, does the integer as a whole represent non-zero? (if this is a "yes" then some representations like sign-and-magnitude would be additionally restricted)
Not necessarily, and in fact sign-and-magnitude is explicitly supported in 6.2.6.2.
Is there a guaranteed way to check if any bit is not set?
If you do not care about padding and sign bits, you could just compare to 0, but this would not work with a 1's complement representation (which is allowed) seeing as all bits 0 and all bits 1 both represent the value 0.
Otherwise: you can read the value of each byte via an unsigned char *, and compare the result to 0:
Values stored in unsigned bit-fields and objects of type unsigned char
shall be represented using a pure binary notation
If you want to check a specific value bit, you could construct a suitable bitmask using (1u << n), but this will not necessarily let you inspect the sign bit.
Is there a guaranteed way to check if any bit is set?
The answer is essentially the same as to the previous question.
Is there a guaranteed way to set the left-most and/or right-most bits?
Do you mean left-most value bit? You could count the bits in INT_MAX or UINT_MAX or equivalent depending on the type, and use that to construct a value (via 1 << n) with which to OR the original value.
If the answer to #1 is "no" how could one iterate over the bits in an integer type and check if each one was a 1 or a 0?
You can do so using a bitmask which you left shift repeatedly, but you can check only the value bits this way and not the sign bit.
For the bitmanipulations you could make a struct with 8 one unsigned bit fields and let the pointer of that struct point to your char. In that way you can easily access each bit. But the compiler will probably do masking under the hood, so it is only a cleaner way for the programmer I think. You must check that your compiler doesn't change the order of the fields when doing this.
yourstruct* pChar=(yourstruct*)(&c)
pChar.Bit7=1;
Let me caveat this by saying I'm addressing C and C++ in general (e.g. C90 and lower, MS Visual C++, etc): the "greatest common denominator" (vs. the latest/greatest cx11 "standard").
Q: If all the bits in an integer type are zero, does the integer as whole represent zero?
A: Yes
Q: If any bit in an integer type is one, does the integer as a whole represent non-zero? (if this is a "yes" then some representations like sign-and-magnitude would be additionally restricted)
A: Yes. This includes the sign bit, for a signed int.
I'm frankly not familiar with "magnitude"
Q: Is there a guaranteed way to check if any bit is not set?
A: "And'ing" a bitmask is always guaranteed.
Q: Is there a guaranteed way to check if any bit is set?
A: Again, "and'ing" a bitmask is always guaranteed.
Q: Is there a guaranteed way to set the left-most and/or right-most bits?
A: I believe you should always have a "MAX_INT" available for all implementations/all architectures to determine the leftmost bit.
I'm prepared to be flamed ... but I believe the above is accurate. And I hope it helps.
IMHO...

What does this & operator mean here?

I was reading some tutorial about openGL in qt.
One of the mouse event slot has this code in it:
if (event->buttons() & Qt::LeftButton) {
rotationX += 180 * dy;
rotationY += 180 * dx;
updateGL();
}
what does the & operator do in the if statement?
is it exactly the same as == ?
It is not the same as ==. It is bitwise AND operator. What the expression does is that it takes the return value from event->buttons() and bitwise AND's it with the value represented by Qt::LeftButton. If the resulting value is non-zero the block is being executed.
In essence, it checks if the button specified by Qt::LeftButton is held down.
The reason why the bitwise AND operator is used here is something called a bitmask. What it means is that the return value of event->buttons() is just a value which has it's bits represent different kinds of states. What is done with the &-operator here is that it checks if certain bits(denoted by Qt::LeftButton) are being set(1) or unset(0) in the value returned by event->buttons(). The return value is zero if no tested bit is set, and non-zero, if at least one of the tested bits is set.
More details of how bitwise operations work can be found here: Wikipedia article about Bitwise operations
That will test that the value event=>buttons() has the bit Qt::LeftButton.
The result would be a 0, if it did not have that bit. and a Qt::LeftButton if it did include that bit.
it is a comparison to check the existence of a flag or bit value on a number
0001 == 1
0010 == 2
0011 == 3
1 & 2 == 0 (false)
1 & 3 == 1 (true)
2 & 3 == 2 (true)
essentially it is a match across the two values for their bit values.
(0001)
& (0010)
---------
(0000) //Neither have the same bit
(0011)
& (0010)
---------
(0010) //both have bit 2
(0101)
& (0110)
---------
(0100) // Both have the 3rd bit
(0111)
& (0110)
---------
(0110) // Both have the 2nd and 3rd bit
Boolean values in C languages are 0 for false. and anything non zero is true.
This proved that the 1st and 2nd bit are available in the number 3. however 1 and 2 do not have matching bits.
Look into bitwise operators. to get a better understanding.
http://en.wikipedia.org/wiki/Bitwise_operation
It's the bitwise AND operator.
0011
& 0101
------
0001
event->buttons() presumably returns a value that's a combination of bits where each bit represents one button. Qt::LeftButton is going to be a value that probably has just a single bit set in the position that corresponds to the "left button". Using bitwise AND (&) here ANDs the individual bits of those two values, and the condition will be considered true if the result is non-zero.
Since there's only one bit in Qt::LeftButton, the only way to get a non-zero value is if event->buttons() has the same bit set. (It may have other bits set too, but those go away when they're ANDed with the zero bits in those positions in Qt::LeftButton. Effectively, then, the expression means "true if and only if event->buttons() includes the bit represented by Qt::LeftButton".
This is the bitwise AND operator. The better question is: What's the job of the AND operator here? Why are we using such a "low-level" method here?
We got a set of flags here. The set of buttons held down is represented by event->buttons(). That means, it is the sum of all buttons held down. But every button is a unique power of two, so the sum of all buttons held down is a set of bits in an integer. I hope you understand this, as this is an essential part of how we can represent simple sets of limited elements in C / C++.
The point is, every bit in the so-called bitset represents one element in the set. So does every element have a unique number, which we have to be able to test against the bitset (if it is contained in the bitset).
If you want to test whether or not the left button was held down during the event, you have to check whether or not the bit is set in the bitset. This is done using the bitwise AND operator, as this combines all the bits of the operands bit for bit using the boolean AND operation. As you should know, the AND oepration returns true if and only if both of the input bits are true. So the bitwise AND operation works as a mask for the input bits. The right operand "filters out" the bits of the left operand which are present in the right operand.
As the if condition is interpreted as true if and only if the value is unequal zero, this equals the question whether or not the bits of the right operand also appear in the left operand. In this concrete scenario, this means: Is the value Qt::LeftButton bitwise contained in the value event->buttons(), or: is the bit represented by Qt::LeftButton contained in the bitset represented by event->button()?
Or simply: Is the left button held down?

How can I set all bits to '1' in a binary number of an unknown size?

I'm trying to write a function in assembly (but lets assume language agnostic for the question).
How can I use bitwise operators to set all bits of a passed in number to 1?
I know that I can use the bitwise "or" with a mask with the bits I wish to set, but I don't know how to construct a mask based off some a binary number of N size.
~(x & 0)
x & 0 will always result in 0, and ~ will flip all the bits to 1s.
Set it to 0, then flip all the bits to 1 with a bitwise-NOT.
You're going to find that in assembly language you have to know the size of a "passed in number". And in assembly language it really matters which machine the assembly language is for.
Given that information, you might be asking either
How do I set an integer register to all 1 bits?
or
How do I fill a region in memory with all 1 bits?
To fill a register with all 1 bits, on most machines the efficient way takes two instructions:
Clear the register, using either a special-purpose clear instruction, or load immediate 0, or xor the register with itself.
Take the bitwise complement of the register.
Filling memory with 1 bits then requires 1 or more store instructions...
You'll find a lot more bit-twiddling tips and tricks in Hank Warren's wonderful book Hacker's Delight.
Set it to -1. This is usually represented by all bits being 1.
Set x to 1
While x < number
x = x * 2
Answer = number or x - 1.
The code assumes your input is called "number". It should work fine for positive values. Note for negative values which are twos complement the operation attempt makes no sense as the high bit will always be one.
Use T(~T(0)).
Where T is the typename (if we are talking about C++.)
This prevents the unwanted promotion to int if the type is smaller than int.