|
Yep. I used to do that myself.
#define true (1==1)
#define false (1==0) If your language does not define values, it's the only sensible way to do it.
Ideological Purity is no substitute for being able to stick your thumb down a pipe to stop the water
|
|
|
|
|
Surely a zero is the same size whatever the width of numbers? For negative values you have to be careful but zero and small positive integers should work for everywhere.
That's quite a neat way of defining true, except that it presumably results in an extra comparison taking place in every test where you use it.
|
|
|
|
|
It's not the size, it's how you use it
|
|
|
|
|
Simple, where the value isn't boolean or a pointer, don't use that technique to test for 0.
In C, I always used "if (c == 0)" for integer values, "if (c)" for booleans. Its the only safe way to do it, as there's no safe value for "true" for an integer.
e.g. in bitwise arithmetic, commonly a bitfield may be tested for one or more of a number of bits set using a mask. The result may be 0 (none set) or some non-zero value (where 1 or more is set). In this case, the C behaviour works as expected, and indeed it was designed for exactly this kind of usage.
|
|
|
|
|
Rob Grainger wrote: e.g. in bitwise arithmetic, commonly a bitfield may be tested for one or more of
a number of bits set using a mask. The result may be 0 (none set) or some
non-zero value (where 1 or more is set). In this case, the C behaviour works as
expected, and indeed it was designed for exactly this kind of usage.
Works as expected? What if 'one or more flag set' is still too weak a condition? What if you need to know wether or not all flags in the mask are set? We really have three cases here and using the C behavior here may actually be suboptimal:
LONG lResult = lFlagWord & lMask;
if(lResult == 0)
{
}
else if(lResult == lMask)
{
}
else
{
}
And from the clouds a mighty voice spoke: "Smile and be happy, for it could come worse!"
And I smiled and was happy And it came worse.
|
|
|
|
|
Hey, I went and looked this up, the standard states explicitly that
"In both forms, the first substatement is executed if the expression compares unequal to 0."
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf[^] page 147
That is, negative numbers are defined by standard to be true for conditional expressions.
|
|
|
|
|
(edit: I posted this as a reply to a message that is now now longer there, oh well)
I do not write out the boolean, but I do write each condition on a new line.
In addition to that, I start the new line with the operator, this way, it is very easy to see at the beginning of the line that it is a continuation of the previous line, and what the operation is:
if( flag1
&& (someOtherFlagThatWillSqrewWithTheLayout == MagicNumbers.Ten)
&& (flag3 == somethingElseCompletely))
{
...
}
I use this style with anything that will make a line of code too long:
var firstChildRow= SomeTypedDataSetWithSillyLongNameThatFillsTheEntireCodeWindow.Tables[0].ChildRelations[0].ChildTable.Rows[0];
var firstChildRow= SomeTypedDataSetWithSillyLongNameThatFillsTheEntireCodeWindow
.Tables[0]
.ChildRelations[0]
.ChildTable
.Rows[0];
|
|
|
|
|
I came from the same dark ages and indeed untill some time ago i also had the tendency to check the boolean value. Particularly the BOOL was a nasty one as you could (with good sense) only check that to FALSE. One other 'trick' i got used to apply was swapping the variable and the value
E.g.
if(FALSE != flag)
{
Logically this seems a bit odd but then again it did protect me against typo's like:
if( flag = FALSE)
{
Today this will generate a compiler warning but that has not always been the case and if you have a special vendor type compiler; you may still face the same.
Why check on FALSE? Simple; that was defined (as 0), any one could set the BOOL to TRUE, 1, 2 etc.
Don't you love the compilers of today? Or better yet, those of tomorrow?
Cheers, AT
Cogito ergo sum
|
|
|
|
|
CDP1802 wrote: why not if (flag == true)?
Indeed, I prefer that when writing in C.
One thing that drives me nuts with C is reading things like:
char* s = ...
if ( s ) ...
|
|
|
|
|
Me too, but then there are the 'noobs' who just know languages like C# or Java and make up smart coding rules which only work as long as they don't ever have to leave their comfortable little world. At times I still have to use some old school methods and have no choice but to ditch object orientation or *gasp* use branching instructions (that's something like GOTO). Our 'modern' friends would not get very far with their 'must do this' and 'don't do that' rules.
And from the clouds a mighty voice spoke: "Smile and be happy, for it could come worse!"
And I smiled and was happy And it came worse.
|
|
|
|
|
OP used C#. It might possibly look like it could be an other language, but the pre tag has lang="cs".
Comparing bools with constants is nonsensical in C#.
Comparing bools with constants in x86 assembly makes even less sense and takes special effort just to do it wrong.
|
|
|
|
|
harold aptroot wrote: Comparing bools with constants is nonsensical in C#.
And it's in no way harmful. But it is consistent with other comparisons.
harold aptroot wrote: Comparing bools with constants in x86 assembly makes even less sense and takes
special effort just to do it wrong.
That I see differently. Defining a boolean type and declaring adequate constants to use with it eliminates most of the problems. Of course only if you use your boolean type for boolean values and nothing else. Unfortunately there is no way to limit your boolean type to just 'true' and 'false' and there is also no mechanism to enforce the use of your boolean type. As always, this is the point where only discipline helps.
And let's not forget this little detail:
int x = -5;
if(x)
{
}
else
{
}
And from the clouds a mighty voice spoke: "Smile and be happy, for it could come worse!"
And I smiled and was happy And it came worse.
|
|
|
|
|
Yes but that's C, not x86 assembly.
Suppose you have a nice boolean in the flags, say the Z flag, and you want to compare it with a constant..
mov eax,0
setz al
cmp eax,someconstant
Ok maybe that's not the best possible way to do it, but it doesn't really matter. Whatever you do, it will be completely useless and you might as well have used the flag directly.
And actually, it is harmful. It will take yet an other second to mentally decode what the heck is going on.
|
|
|
|
|
harold aptroot wrote: Yes but that's C, not x86 assembly.
Sorry, there I was in the wrong show. It's friday afternoon
And from the clouds a mighty voice spoke: "Smile and be happy, for it could come worse!"
And I smiled and was happy And it came worse.
|
|
|
|
|
And yet that style of testing for non-null is the standard in, for example, JavaScript. (Personally I have no problem with it in C either, for pointer or unsigned types ... with signed values it's bad because as pointed out someone could potentially switch negative values' interpretation out from under you.)
When comparing against something which is (semantically or definitively, depending on your language) a boolean, though, there's absolutely no reason to make the reader parse more text before he can understand your statement. Adding the ' == true' provides zero clarification value, as anyone who vaguely knows the language knows that if tests check for a true value. In your example here, adding the ' != NULL' does provide a little clarification, so it's pretty much a value-neutral stylistic choice to add it or not.
(Someone might suggest that NULL could evaluate to true, but anyone who makes that #define is far more culpable for any confusion than the person who writes the check you put here, and in any professional context that won't be the case.)
|
|
|
|
|
BobJanova wrote: Adding the ' == true' provides zero clarification value
Exactly! Not only that, it also adds the potential for a catastrophic typo: =true instead of ==true .
I'd even go so far as to include comparisons to user-defined symbols that represent boolean states, such as TRUE and FALSE : if if(x) is not equivalent to if(x==TRUE) , then the definitions are wrong, since they do not adhere to the rules of boolean logic! In that case not the comparison needs to be 'fixed', but the definitions!
|
|
|
|
|
Don't see why. The C language explicitly defines that comparison to work for null vs. non-null values, with the expected behaviour.
|
|
|
|
|
That in combination with the inabiliy to properly initialize a variable has ruined more than one day...
Cheers, AT
Cogito ergo sum
|
|
|
|
|
CDP1802 wrote: t is at least the same way you compare any other variable (if (x == 0), so why
not if (flag == true)?
My reasoning is you could take any boolean expression, and instead of writing
if (X) you could write
if (X==true) to make it really clear. But you could then also write
if ((X==true)==true) to make it really really clear.
So I'm thinking let's drop all implied trailing "==true"'s in a mental tail call optimization.
|
|
|
|
|
And I think your reasoning would be wrong. It IS more clear to write if (X==true). Just because you don't like it does not mean it is not more clear, especially to junior programmers. I am the senior lead and I instruct ALL of our programmers under me to write if (X==true). It doesn't cost the compiler anything and it makes it understandable by even the junior most person quickly. It is all about proper maintenance and thinking about the coder behind you instead of just yourself.
X is a variable so comparing it like another variable is both consistent and readable.
|
|
|
|
|
This is, at best, a matter of opinion. For me it is less clear to write if(x == true) because I have to read twice as much text to get the meaning &dnash; just as it's unclear to give a method a 300 character name. I have never met anyone who is confused by if(booleanVariable) and if they are then they shouldn't be programming until they learn the language they're using – if they have trouble reading that then do you really want them poking around your pointer code, or reflection in C#, or constructor injection frameworks, or any of the other million things any real world app has that are far more confusing?
Readability is all about having a single, clear, unambiguous meaning for a statement as quickly as possible. if(x) and if(!x) are short, clear and obviously different from each other (as long as you're using a font where ! is more than 2 pixels wide, heh). if(x == true) adds nothing, is easier to mix up with closely related but different statements (if(x = true) or if(x == True) or if(x == "true") etc) and doesn't immediately show that x is a boolean or castable to one until you read the whole thing.
You are on your way to becoming one of the micromanaging senior leads who appear on The Daily WTF issuing that kind of order based on your personal opinion of readability.
|
|
|
|
|
Why do boolean variables exist? To store and retrieve boolean expressions (TRUTH values). They were invented SO THAT we can write code like
if (X) otherwise we could just as well remove the boolean type and work with integer flags like
if (X==1) This was one of the issues people had with C. No proper boolean type. But now we have a proper boolean type so don't reduce it to a "flag value" that needs to be compared to something to find the truth. It holds the truth all on its own. That's its job.
|
|
|
|
|
Believe it or not, but my high school teacher recommended doing this "because it's more clear". I was the only one ignoring that and only got flak for it.
|
|
|
|
|
Perhaps that is why he was a high school teacher.
|
|
|
|
|
Which just show that there are 10 types of people in the world ...
|
|
|
|