Here is my code snippet:
int a;
if(a=8)
cout<<"Its right";
else
cout<<"Not at all";
getch();
return(0);
I'm getting the output Its right while I've not give any input there its just a assignment to the a=8.
**Borland Compiler** gives the following 2 warnings and executes the code.
1: Possible incorrect assignment (a=8)
2: 'a' is assigned a value that is never used.
When you write:
if(a=8)
You're assigning 8 to the variable a, and returning a, so you're effectively writing:
a = 8;
if(a)
This is non-zero, and hence treated as "true".
I (and the compiler) suspect you intended to write (note == instead of =):
if(a==8)
This is why you get the warnings. (Note that, in this case, a is still uninitialized, so the behavior is undefined. You will still get a warning, and may still return true...)
a = 8 assign 8 to a and returns the value of the assignment, that is 8. 8 is different from 0 and thus is considered true. the test apsses, and the program outputs "Its right".
you may have written if ( a == 8 ) which correctly tests the value of a without changing its value.
if(a=8)
implies assign a value of 8 to a and then use it to evaluate for the if statement. Since 8 is nonzero it essentially translates to TRUE (any value that is non-zero is true).
The first warning is because it's a frequent typo to write = in a condition test where you meant ==. The philosophy behind the warning is that it's a lesser burden for a programmer to rewrite if(a=b) to, say if((a=b)!=0) in the few cases he wants that, than to spend frustrating hours debugging the results if he mistakenly got an assignment instead of a comparison.
The second warning is just what it says: It looks like a mistake to have a local variable that you assign a value to but never use.
Since they are just warnings, you're free to ignore them if you think you know what you're doing. The compiler may even provide a way for you to turn them off.
Everyone else's answer is correct :)
if (a = 8) // Sets a to be 8 (and returns true so the if statement passes)
if (a == 8) // Check to see if a is equal to 8
I just want to add that I always (force of habit!) write if statements this way :
if (8 == a) {
Now, if I miss out one of the =, the compiler doesn't give me a warning, it gives me an error :)
You need a == (double equals). Single = is an assignment; when treated as an expression as you have done here, it evaluates to the value assigned, in this case 8. 0 is treated as False and anything else is True, so (a=8) == 8 == True.
Related
Output of boost::lexical_cast with a bool variable as input is expected to be a 0 or 1 value. But I get different value instead.
It's not something which happen normally. Let's take a look at example code I've wrote:
#include <string>
#include <boost/lexical_cast.hpp>
int main()
{
bool alfa = true; // Doesn't metter whether alfa is initialized at definition or not
char beta = 71; // An integer value. Different values don't make any differences.
memcpy(&alfa, &beta, sizeof(alfa));
printf("%s\n", boost::lexical_cast<std::string>(alfa).c_str());
}
From this code, I've got "w" (ASCII code of w is 71) as output! But I expected it to be a 0 or 1 value.
The problem is just the value that bool variable will cast into. The bool variable in the given example is already considered true.
What causes problem is imagine I want to convert back the converted value. That's where it throws exception because for example "w" character can't be converted to bool. But if the output was 0 or 1, re-conversion would be possible.
std::string converted_value = boost::lexical_cast<std::string>(alfa);
bool reconverted_value = boost::lexical_cast<bool>(converted_value ); // In this line, boost::bad_lexical_cast will be thrown
I was wondering whether the output is right or this is a bug in boost::lexical_cast?
Also when I was trying to do the same thing and cast the variable to int, I faced boost::bad_lexical_cast exception.
My boost version: 1.58
Live sample
The C++ standard does not specify how a Boolean is stored in memory, only that there are two possible values: true and false. Now, on your machine, I presume these are stored, respectively, as 1 and 0. The compiler is allowed to make assumptions, and in particular it's allowed to assume that these are going to be the only two values stored in a Boolean.
Thus, when boost::lexical_cast sees a Boolean, it runs code that probably looks something like this (after optimization)
// Gross oversimplification
std::string lexical_cast(bool value) {
char res = '0' + (int)value;
return std::string(1, res);
}
If value is 0 or 1, this works fine and does what you want. However, you put a 71 into it. So we add the ASCII code of '0' (48) to 71 and get 119, the ASCII code of 'w'.
Now, I'm not a C++ standard expert, but I would guess that storing a non-standard value into a Boolean with memcpy is undefined behavior. At the very least, your code is non-portable. Perhaps someone more versed in the standard can fill in the holes in my knowledge as far as that's concerned.
You broke the rules. What did you expect, that C++ would add useless code to your program to catch rule-breakers?
Boolean variables can only be 0 or 1, false or true. And they are, if you assign to them properly, according to the rules.
If you memcpy them or reinterpret_cast then the underlying implementation shows through. A bool is a memory byte. If it somehow gets set to something other than 0 or 1 then there it is.
I'd have to double-check but I'm not even sure you are guaranteed that a bool is one byte. I think you can take a pointer to it. But if the hardware had some way to create a pointer to one bit, you could be quite surprised at what C++ did with that.
Is it possible to do the following without getting a stackoverflow?
int foo(int i = 0)
{
return foo(--i) || i;
}
When foo(--i) evaluates to 0, it should return false, therefore returning i and ending the execution.
You want return !i || foo(--i).
Note that || is short-circutted. This means that evaluation (which is performed from left to right) will continue for only as long as the result of the expression is not known. So the way I've written it, the case i being zero will block the recursion.
(Moving on to more advanced issues, you need to be very careful when evaluating expressions when the same variable appears in more than one sub-expression and it's value is changed in some of them. My having !i and --i could get me in trouble: I'm not too far away from undefined behaviour here. In fact, it turns out that my code is completely safe since || is a sequence point and the order of evaluation with || is well-defined. But do be careful.)
From what you have coded foo never returns because it will continuosly go on decreasing i and recurse. You need a check inside foo which returns whatever you want when you get i as 0.
I have this class which has a private bool member variable call positive. I want to check to see if both my class and the number I am adding to it are both positive so I wrote the expression
positive == (n > 0) //n is of type int
But for some reason when both are positive this evaluates to false. I then did a cout on positive and it has a value of 204! I though a boolean only holds 1 or 0. That would be why this is evaluating to false but why is that and how do I fix it? I am using Visual Studio 2013.
Just to clarify it should be == because I want to know if the sign is the same. So I want it to be true if both are negative or both are positive. I think I solved the problem which was that positive in one particular test case wasn't being initialized. But still why would a bool variable even if uninitialized contain a value larger and 1?
As per the standard, getting the value of an uninitialized variable is undefined behavior.
Since the actual size of a bool can be more than one bit, a bool variable containing rubbish can even hold bad values like 254. Welcome in the C++ hell!
And since (n > 0) evaluates to 1, 254 == 1 is false.
The bug is most likely due to the fact that positive never got a meaningful value since the object that contains it come into existence.
Search for a positive = something into your code and see if it is executed at least once before you use it.
Edited after Konrad comment:
The problem is most likely due to the fact that == is implemented between int-s and not bool-s relying on a bool-to-int promotion assuming the implementation of bool use 0 for false and 1 for true (and since && and || between int-s assume 0 for false and non-zero for true, bool-to-int promotion can be an identity).
This can be seen as a "compiler unfairness", but -since in the space of integer there is one false and bilions of trues- if operator==(bool,bool) was applied, there where more chance the uninitialized bug wold have been not discovered.
Treating bool as int in the arithmetic operations (not logic ones) makes bad-bool values to come out, thus revealing the bug.
Of course, since behind it there is an UB, it's all in an implementation choice. And it is int the freedom of each reading this to think I'm try to sell a bug as a feature.
Oh, you have a == where you should have an =.
The == doesn't assign, it checks for equality
Should be
bool positive = (n > 0) //n is of type int
bool generally holds only 1 or 0 after assignment. The only reason I can imagine you would see 204 in a bool is if the variable was uninitialized (so it had a junk value).
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to check for equals? (0 == i) or (i == 0)
Why does one often see “null != variable” instead of “variable != null” in C#?
Why do some experienced programmers write expressions this way?
What is the meaning of NULL != value in C++?
For example,
int k =5;
if( 5 == k )
{
}
is preferred over
if (k == 5)
{
}
Is it considered only for formatting purpose or is there any reason behind it?
Because that form makes it harder to introduce a bug by forgetting one of the equals signs. Imagine if you did this:
if (k = 5)
This was intended as a comparison, but it's now an assignment! What's worse, it is legal, and it will mess up your program in multiple ways (the value of k is changed, and the conditional always evaluates to true).
Contrast this with
if (5 = k)
This is not legal (you cannot assign to a literal) so the compiler will immediately flag it as an error.
That said, this style of writing code (assignments within conditionals) is not as prevalent today as it once was. Most modern compilers will flag this as a warning, so it's unlikely to go undetected. Personally I don't like the second form and since the compiler is there to help I don't use it.
If you mistype and write
if (k = 5) // instead of ==
then you likely just introduced a hard to find bug. (Actually, it used to be hard to find. Nowadays, most compilers will flag this as a warning.)
This, however, will result in a compile-time error
if (5 = k)
BTW, this style is called Yoda Conditions :-)
It's to avoid the mistake of
if( k = 5 ) {
}
which would always equal true.
A. Who said it's preferred ?!
the only reason i can think of it's to avoid:
int k =5;
if( 5 = k )//notice one "="
{
}
like this you will get a compilation error, while the other way will work. but I think it's less readable and less preferred.
First of all, most people prefer the second form, since it feels "more natural"; the first form is felt as "reversed", and in fact is often called "Yoda conditional".
The rationale behind using the first form is to avoid accidental assignment when typing = instead of == by error. Since in a conditional you can write any expression, = is allowed, so in case of mistyping the instruction
if(k = 5)
{
}
won't check if k is equal to 5, but will assign 5 to k and, since = returns a reference to its left hand operator, the condition will be evaluated as true and the if body will always be executed.
On the other hand, if you typed = instead of == in the Yoda conditional you would get
if(5 = k)
{
}
which results in a compilation error, since you can't assign anything to a literal (5).
Although they look like a good idea, "Yoda conditionals" are quite weird looking, and, most importantly, almost any good compiler with warnings turned on will warn you anyway if you write an assignment inside a conditional expression, so most people just use the "natural looking" form.
It's because a common typo is typing = instead of ==.
Just read on an internal university thread:
#include <iostream>
using namespace std;
union zt
{
bool b;
int i;
};
int main()
{
zt w;
bool a,b;
a=1;
b=2;
cerr<<(bool)2<<static_cast<bool>(2)<<endl; //11
cerr<<a<<b<<(a==b)<<endl; //111
w.i=2;
int q=w.b;
cerr<<(bool)q<<q<<w.b<<((bool)((int)w.b))<<w.i<<(w.b==a)<<endl; //122220
cerr<<((w.b==a)?'T':'F')<<endl; //F
}
So a,b and w.b are all declared as bool. a is assigned 1, b is assigned 2, and the internal representation of w.b is changed to 2 (using a union).
This way all of a,b and w.b will be true, but a and w.b won't be equal, so this might mean that the universe is broken (true!=true)
I know this problem is more theoretical than practical (a sake programmer doesn't want to change the internal representation of a bool), but here are the questions:
Is this okay? (this was tested with g++ 4.3.3) I mean, should the compiler be aware that during boolean comparison any non-zero value might mean true?
Do you know any case where this corner case might become a real issue? (For example while loading binary data from a stream)
EDIT:
Three things:
bool and int have different sizes, that's okay. But what if I use char instead of int. Or when sizeof(bool)==sizeof(int)?
Please give answer to the two questions I asked if possible. I'm actually interested in answers to the second questions too, because in my honest opinion, in embedded systems (which might be 8bit systems) this might be a real problem (or not).
New question: Is this really undefined behavior? If yes, why? If not, why? Aren't there any assumptions on the boolean comparison operators in the specs?
If you read a member of a union that is a different member than the last member which was written then you get undefined behaviour. Writing an int member and then reading the union's bool member could cause anything to happen at any subsequent point in the program.
The only exception is where the unions is a union of structs and all the structs contain a common initial sequence, in which case the common sequence may be read.
Is this okay? (this was tested with g++ 4.3.3) I mean, should the compiler be aware that during boolean comparison any non-zero value might mean true?
Any integer value that is non zero (or pointer that is non NULL) represents true.
But when comparing integers and bool the bool is converted to int before comparison.
Do you know any case where this corner case might become a real issue? (For example while binary loading of data from a stream)
It is always a real issue.
Is this okay?
I don't know whether the specs specify anything about this. A compiler might always create a code like this: ((a!=0) && (b!=0)) || ((a==0) && (b==0)) when comparing two booleans, although this might decrease performance.
In my opinion this is not a bug, but an undefined behaviour. Although I think that every implementor should tell the users how boolean comparisons are made in their implementation.
If we go by your last code sample both a and b are bool and set to true by assigning 1 and 2 respectfully (Noe the 1 and 2 disappear they are now just true).
So breaking down your expression:
a!=0 // true (a converted to 1 because of auto-type conversion)
b!=0 // true (b converted to 1 because of auto-type conversion)
((a!=0) && (b!=0)) => (true && true) // true ( no conversion done)
a==0 // false (a converted to 1 because of auto-type conversion)
b==0 // false (b converted to 1 because of auto-type conversion)
((a==0) && (b==0)) => (false && false) // false ( no conversion done)
((a!=0) && (b!=0)) || ((a==0) && (b==0)) => (true || false) => true
So I would always expect the above expression to be well defined and always true.
But I am not sure how this applies to your original question. When assigning an integer to a bool the integer is converted to bool (as described several times). The actual representation of true is not defined by the standard and could be any bit pattern that fits in an bool (You may not assume any particular bit pattern).
When comparing the bool to int the bool is converted into an int first then compared.
Any real-world case
The only thing that pops in my mind, if someone reads binary data from a file into a struct, that have bool members. The problem might rise, if the file was made with an other program that has written 2 instead of 1 into the place of the bool (maybe because it was written in another programming language).
But this might mean bad programming practice.
Writing data in a binary format is non portable without knowledge.
There are problems with the size of each object.
There are problems with representation:
Integers (have endianess)
Float (Representation undefined ((usually depends on the underlying hardware))
Bool (Binary representation is undefined by the standard)
Struct (Padding between members may differ)
With all these you need to know the underlying hardware and the compiler. Different compilers or different versions of the compiler or even a compiler with different optimization flags may have different behaviors for all the above.
The problem with Union
struct X
{
int a;
bool b;
};
As people mention writing to 'a' and then reading from 'b' is undefined.
Why: because we do not know how 'a' or 'b' is represented on this hardware. Writing to 'a' will fill out the bits in 'a' but how does that reflect on the bits in 'b'. If your system used 1 byte bool and 4 byte int with lowest byte in low memory highest byte in the high memory then writing 1 to 'a' will put 1 in 'b'. But then how does your implementation represent a bool? Is true represented by 1 or 255? What happens if you put a 1 in 'b' and for all other uses of true it is using 255?
So unless you understand both your hardware and your compiler the behavior will be unexpected.
Thus these uses are undefined but not disallowed by the standard. The reason they are allowed is that you may have done the research and found that on your system with this particular compiler you can do some freeky optimization by making these assumptions. But be warned any changes in the assumptions will break your code.
Also when comparing two types the compiler will do some auto-conversions before comparison, remember the two types are converted into the same type before comparison. For comparison between integers and bool the bool is converted into an integer and then compared against the other integer (the conversion converts false to 0 and true to 1). If the objects being converted are both bool then no conversion is required and the comparison is done using boolean logic.
Normally, when assigning an arbitrary value to a bool the compiler will convert it for you:
int x = 5;
bool z = x; // automatic conversion here
The equivalent code generated by the compiler will look more like:
bool z = (x != 0) ? true : false;
However, the compiler will only do this conversion once. It would be unreasonable for it to assume that any nonzero bit pattern in a bool variable is equivalent to true, especially for doing logical operations like and. The resulting assembly code would be unwieldy.
Suffice to say that if you're using union data structures, you know what you're doing and you have the ability to confuse the compiler.
The boolean is one byte, and the integer is four bytes. When you assign 2 to the integer, the fourth byte has a value of 2, but the first byte has a value of 0. If you read the boolean out of the union, it's going to grab the first byte.
Edit: D'oh. As Oleg Zhylin points out, this only applies to a big-endian CPU. Thanks for the correction.
I believe what you're doing is called type punning:
http://en.wikipedia.org/wiki/Type_punning
Hmm strange, I am getting different output from codepad:
11
111
122222
T
The code also seems right to me, maybe it's a compiler bug?
See here
Just to write down my points of view:
Is this okay?
I don't know whether the specs specify anything about this. A compiler might always create a code like this: ((a!=0) && (b!=0)) || ((a==0) && (b==0)) when comparing two booleans, although this might decrease performance.
In my opinion this is not a bug, but an undefined behaviour. Although I think that every implementor should tell the users how boolean comparisons are made in their implementation.
Any real-world case
The only thing that pops in my mind, if someone reads binary data from a file into a struct, that have bool members. The problem might rise, if the file was made with an other program that has written 2 instead of 1 into the place of the bool (maybe because it was written in another programming language).
But this might mean bad programming practice.
One more: in embedded systems this bug might be a bigger problem, than on a "normal" system, because the programmers usually do more "bit-magic" to get the job done.
Addressing the questions posed, I think the behavior is ok and shouldn't be a problem in real world. As we don't have ^^ in C++ I would suggest !bool == !bool as a safe bool comparison technique.
This way every non-zero value in bool variable will be converted to zero and every zero is converted to some non-zero value, but most probably one and the same for any negation operation.