• Advertisement
Sign in to follow this  

Assuming true equals 1

This topic is 4482 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I hate asking dumb questions, but this has me curious. I use C/C++ with the MSVC.net compiler, and my program will be compiled with it only. I'm not so much worried about different compiler behavior, but any information about such things would also be interesting. Anyway, my concern isn't whether the defined value for 'TRUE' or 'true' is 1. It's whether the return values of a bool statement is always 1. Here are some examples: int value = ( number < max ); int value = ( max < number ); int value = ( number & max ); // I know this will not always be 1 or 0 - but not really a bool statement int value = ( number == max && max > 6 ); Is it safe to assume a 1 or 0 with most conditional statements? This is what I'm currently doing in my code, after some conditional statements, and I'm wondering how dumb this type of thing looks: value = ( value ) ? 1 : 0; Thanks for any information.

Share this post


Link to post
Share on other sites
Advertisement
According to the C++ standard (Section 4.7 paragraph 4 for those who care), during integral conversions, true is always converted to 1 and false is always converted to 0.

Share this post


Link to post
Share on other sites
In C++ bool is guaranteed to be 0 or 1 and boolean expressions yield bool's as results.


value = ( value ) ? 1 : 0;

You need something like that if you want to guarantee that value is 1 or 0 and value is not a bool.
Here's a method without any branches:
value = !!vaule;
or
value = (bool)value;
ought to work too.

If value is a bool then it's already 0 or 1.

Share this post


Link to post
Share on other sites
Thanks for the quick replies. I really appreciate it :)

Share this post


Link to post
Share on other sites
I make only the assumptions that true == true, false == false, and true != false. Under C/++, I also assume that integer 0 is considered "false". But I make no bets or assumptions about "true" having any specific value. I've been bit by this under at least one machine language and one VM, so I make no assumptions about how higher-level languages treat it.

Share this post


Link to post
Share on other sites
Note that while the expression (foo) is equivalent to the expression (foo ? 1 : 0), I tend to prefer the latter. It makes it more clear that a boolean mapping is occuring and that the result is an integer. Terseness is often counterproductive in C++.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by Sneftel
Terseness is often counterproductive in C++.


Sadly, this is true.

Share this post


Link to post
Share on other sites
Just a small consideration that's easily missed: bool and BOOL aren't the same. BOOL is probably an integral type, and can hold more than just 0 and 1. Similar, TRUE and FALSE are probably not booleans, but integers as well.

CM

Share this post


Link to post
Share on other sites
Quote:
Original post by Conner McCloud
Just a small consideration that's easily missed: bool and BOOL aren't the same. BOOL is probably an integral type, and can hold more than just 0 and 1. Similar, TRUE and FALSE are probably not booleans, but integers as well.

CM


A simple example is the GetMessage() WinAPI function:
Quote:

BOOL GetMessage(LPMSG, HWND, UINT, UINT);

- If the function retrieves a message other than WM_QUIT, the return value is nonzero.
- If the function retrieves the WM_QUIT message, the return value is zero.
- If there is an error, the return value is -1.

Share this post


Link to post
Share on other sites
In general, you should not need to make such an assumption, and you may make your code harder to maintain by doing so. Also, although this may work in C++, you won't be able to get away with it in a number of other languages. Even in C++ you have to be weary of interfacing with other languages, as true is -1 in VB for example! (See the definition of VARIANT_TRUE in WTYPES.H. I think there's a vTRUE of -1 as well in .NET)

The only thing that really is safe to assume, is that false == 0 and true != 0, and you'd be best to write any expressions in that manner if possible.

Share this post


Link to post
Share on other sites
Quote:
Original post by iMalc
In general, you should not need to make such an assumption

I don't need to assume it. I'm asking if I should. If I absolutely know that bool results are 0 or 1, then does it not look strange to force it to the value? It's similar to having if( value == FALSE ) value = 0; The only difference is perhaps that false is more widely known to always be zero and can't be anything else.

What I'm doing is choosing a starting foot to walk on in a human-like movement animation. When the character begins walking backwards, animation looks the most realistic if they start walking on a certain foot, depending on which direction they are turning to walk that way. IRL, if you're standing, and want to walk nearly the opposite direction that you're facing, and you want to spin clockwise to turn and face that way as you begin walking, then you're probably going to leave your left foot planted on the ground and pull your right foot back. This is what that looks like:
// Start on certain foot when turning mostly around, depending on which direction planning to turn
if( MoveDirection.AngleLength( Forward ) > PI / 2 )
{
// Start on foot opposite to our new direction (0 or 1)
NextStartIndex = ( Forward.CrossY( MoveDirection ) < 0.0f );

// Reverse if the movement anim plays with right foot stepping first
if( Animation->CheckFlag( ANIM_BACKWARDS ) )
NextStartIndex = !NextStartIndex;

// Also reverse (again) if stance is mirrored
if( State.Anim.CheckFlag( STATE_ANIM_MIRROR ) )
NextStartIndex = !NextStartIndex
}
Would this be better?

// Start on certain foot when turning mostly around, depending on which direction planning to turn
if( MoveDirection.AngleLength( Forward ) > PI / 2 )
{
// Start on foot opposite to our new direction (0 or 1)
NextStartIndex = ( Forward.CrossY( MoveDirection ) < 0.0f ) ? 1 : 0;

// Reverse if the movement anim plays with right foot stepping first
if( Animation->CheckFlag( ANIM_BACKWARDS ) )
NextStartIndex = ( NextStartIndex ) ? 0 : 1;

// Also reverse (again) if stance is mirrored
if( State.Anim.CheckFlag( STATE_ANIM_MIRROR ) )
NextStartIndex = ( NextStartIndex ) ? 0 : 1;
}

Share this post


Link to post
Share on other sites
Quote:
Original post by Sneftel
Note that while the expression (foo) is equivalent to the expression (foo ? 1 : 0), I tend to prefer the latter. It makes it more clear that a boolean mapping is occuring and that the result is an integer. Terseness is often counterproductive in C++.


So the compiler treats those two statements the same? I mean one will not generate more code than the other?

Just asking. =)

Share this post


Link to post
Share on other sites
I'd say the 2nd option is better as it's more readable - you're explicitly stating which foot to use rather than relying on the ! operator to alternate between 0 and 1.

Having said that i'd be tempted to replace 0 and 1 by an enum to make it even more readable

eg


enum EFoot
{
eLeftFoot = 0,
eRightFoot = 1,

eMaxFeet
};

// Start on certain foot when turning mostly around, depending on which direction planning to turn
if( MoveDirection.AngleLength( Forward ) > PI / 2 )
{
// Start on foot opposite to our new direction (eLeftFoot or eRightFoot)
NextStartIndex = ( Forward.CrossY( MoveDirection ) < 0.0f ) ? eRightFoot : eLeftFoot;

// Reverse if the movement anim plays with right foot stepping first
if( Animation->CheckFlag( ANIM_BACKWARDS ) )
NextStartIndex = ( NextStartIndex ) ? eLeftFoot : eRightFoot;

// Also reverse (again) if stance is mirrored
if( State.Anim.CheckFlag( STATE_ANIM_MIRROR ) )
NextStartIndex = ( NextStartIndex ) ? eLeftFoot : eRightFoot;
}



Share this post


Link to post
Share on other sites
Quote:
Original post by private_ctor
So the compiler treats those two statements the same? I mean one will not generate more code than the other?

Depends on the compiler and the context of the expression. A compiler may do lazy conversions. That is to say, treats all non-zero values as true, and only converts the value to one when the need for integral conversion is done. So bool b = (foo); may in fact generate different code than bool b = (foo ? 1 : 0); but generate the same code in int i = (foo); and int i = (foo ? 1 : 0);

The same compiler may do different things depending on the compiler switches as well. But this definately falls in the micro optimization category. I wouldn't worry about the efficiency of an int->bool or bool->int conversion.

Share this post


Link to post
Share on other sites
You could just use a BOOL bLeftFoot, where 0 means it's right, and non-zero means left, and you don't need to worry if it's a 1, 2, ~0 or whatever.

Share this post


Link to post
Share on other sites
Quote:
Original post by Gav
I'd say the 2nd option is better as it's more readable - you're explicitly stating which foot to use rather than relying on the ! operator to alternate between 0 and 1.

Having said that i'd be tempted to replace 0 and 1 by an enum to make it even more readable

I agree. I kind of coded that in a hurry just to see if the animations would look better, and ended up leaving it implimented for... seven months. I'm not sure about left/right enums. The operation is sort of a flag-enabled quirk for humanoid characters only. I suppose I could define the enum strictly in the local source file. Think I'll do that.

Quote:
Original post by BeerNutts
You could just use a BOOL bLeftFoot, where 0 means it's right, and non-zero means left, and you don't need to worry if it's a 1, 2, ~0 or whatever.

I would end up having to convert to index values at some point when I use it. The 0 and 1 index into a defined array of starting times for the movement animations. For humanoids, the starting times are either left foot lifting or right foot lifting in a walk-like animation.

Even though I'll probably use enums, it's still nice to know what's going on. Thanks for the details.

Share this post


Link to post
Share on other sites
Dammit, it logged me out and screwed up the post above!

I think you already have the perfect solution, without resorting to this 0's and 1's stuff, nor do you need enums. All you need to do is rename a variable...
if( MoveDirection.AngleLength( Forward ) > PI / 2 )
{
// Start on foot opposite to our new direction (0 or 1)
LeftFootNext = ( Forward.CrossY( MoveDirection ) < 0.0f );

// Reverse if the movement anim plays with right foot stepping first
if( Animation->CheckFlag( ANIM_BACKWARDS ) )
LeftFootNext = !LeftFootNext;

// Also reverse (again) if stance is mirrored
if( State.Anim.CheckFlag( STATE_ANIM_MIRROR ) )
LeftFootNext = !LeftFootNext;
}
All of the expresions above are already boolean expressions.
When LeftFootNext is false, obviously right foot is next. Being a boolean problem in this case, it should definately use boolean types and boolean logic. Only when there is, (or could later be) more than two options should you use the enum approach. (I suspect you're never going to have a 3-legged monster![grin])
See K.I.S.S & Y.A.G.N.I.

Share this post


Link to post
Share on other sites
Quote:
Original post by iMalc
I think you already have the perfect solution, without resorting to this 0's and 1's stuff, nor do you need enums. All you need to do is rename a variable...

Like I said, the value is used to index into an array of starting times. The index (which you termed 'LeftFootNext') is called NextStartIndex, mainly because it pertains to all animations. Not just movement animations, and certainly not just humanoid walking animations. Animations may define any number of starting times. And other than in this type of situation, the engine randomly chooses between them.

There are no left and right feet in the game engine. Character types are not hard coded. Their skeleton and structure information is fed to the engine with scripts and parsed data. This means I have no idea how many legs characters may have. One of the robots I recently made has tank tread, and no legs at all. As I said above, this operation is flag-enabled by character types that want to use it. And even then, characters who don't have left and right legs could still use it to do other strange things.

Quote:
All of the expresions above are already boolean expressions.
When LeftFootNext is false, obviously right foot is next. Being a boolean problem in this case, it should definately use boolean types and boolean logic. Only when there is, (or could later be) more than two options should you use the enum approach. (I suspect you're never going to have a 3-legged monster![grin])

Indeed, I suspect I will have eight legged monsters. But if these monsters define their movement animation's first two starting times as the ones that look best to turn around while starting to move, then they can still use the feature. I need index logic, not boolean logic.

Quote:
See K.I.S.S & Y.A.G.N.I.

Ha ha. Come on man, you have to be kidding. It's an index that references starting times for an animation. It is simple.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement