Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » operator++(bool)

This thread is locked; no one can reply to it. rss feed Print
 1   2 
operator++(bool)
Peter Hull
Member #1,136
March 2001

Did you know this was valid C++

#include <iostream>
using std::cout;
using std::endl;

int main ()
{
  bool b = false;
  cout << b << endl;
  b++;
  cout << b << endl;
  b++;
  cout << b << endl;
  return 0;
}

You can call increment on false to get true, and increment on true to get ... true.
And if you replace ++ with -- , that's not valid C++.

I only found this out just today; it's been slated to be deprecated in C++17 (link) Enjoy while you can!

Chris Katko
Member #1,881
January 2002
avatar

WHAT? I thought for sure (bool)++ was negate. This is like Javascript-level stupidity.

video

Is that compiler dependent?

[edit] Also, side note: Lots of people I know are surprised that you can multiply strings in some (read: good) languages. It just means repeat. Which is insanely useful when you need to do something like:

print "text header\n" + "-"*80 + "\n"

As well as other formatting I can't recall off the top my head. I love learning about stuff like that where you go "Where has this been all my life?"

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

torhu
Member #2,727
September 2002
avatar

Is b++ just the same as b = true? Anyone tested it or looked at the assembly?

By the way, negation would be b ^= 1. Unless C++ disallows it, of course :P

Chris Katko
Member #1,881
January 2002
avatar

#SelectExpand
1#include <stdio.h> 2int main() 3{ 4 bool a = false; 5 bool b = true; 6 printf("a = %i\n", a); 7 printf("b = %i\n", b); 8 9 printf("a++ = %i\n", (a++) ); 10 printf("b++ = %i\n", (b++) ); 11 12 a = false; 13 b = true; 14 printf("++a = %i\n", (++a) ); 15 printf("++b = %i\n", (++b) ); 16 17 a = false; 18 b = true; 19 printf("!a = %i\n", !a); 20 printf("!b = %i\n", !b); 21 22 a = false; 23 b = true; 24 printf("a^1 = %i\n", a^1); 25 printf("b^1 = %i\n", b^1); 26 27 28 //lol. 29 a = false; 30 b = true; 31 printf("(1 - (bool)a*-1) = %i\n", 1 - (bool)(a*-1)); 32 printf("(1 - (bool)b*-1) = %i\n", 1 - (bool)(b*-1)); 33 }

a = 0
b = 1
a++ = 0 //nope
b++ = 1 //nope
++a = 1 //nope
++b = 1 //nope
!a = 1 //yes
!b = 0 //yes
a^1 = 1 //yes
b^1 = 0 //yes
1 - (bool)a*-1 = 1 //yes
1 - (bool)b*-1 = 0 //yes... lols

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

torhu
Member #2,727
September 2002
avatar

With the postfix operators you have to increment and print them in two different statements, otherwise you get the original value ;)

But it looks like bools are limited to be either 0 or 1. I guess b + 1 would be 1?

By the way, what compiler version did you use?

Arthur Kalliokoski
Second in Command
February 2005
avatar

What possible reason would you have to increment a bool anyway? Either set it to true or false, anything else is madness. Using ischar() as a number base makes about as much sense.

They all watch too much MSNBC... they get ideas.

Elias
Member #358
May 2000

Well, looking at it from C it makes sense - there bool is the same as int and anything except zero means true. So if x is 1 and you do x++ it gets 2, which is still true.

It is stupid that they allowed ++ for bool in C++, but so are 1000 other things in C++, so I don't see anything special here :P

--
"Either help out or stop whining" - Evert

Chris Katko
Member #1,881
January 2002
avatar

I forgot to mention I'm running GCC. I don't recall the version, it's in the newer (maybe experimental?) branch which is necessary for proper c++14 (or whatever) support. I don't recall which, it's been a long time since I had to install it.

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

Mark Oates
Member #1,146
March 2001
avatar

Elias said:

Well, looking at it from C it makes sense

Why not x-- then?

As it is, you can flip false to true, or true to true, but not true to false. I would think the operators should be symmetrical, or not at all.

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

Arthur Kalliokoski
Second in Command
February 2005
avatar

Elias said:

So if x is 1 and you do x++ it gets 2, which is still true.

But why would you do that with a bool, as opposed to some sort of stack pointer or ring buffer? Not to mention the wraparound, which is admittedly huge.

They all watch too much MSNBC... they get ideas.

Peter Hull
Member #1,136
March 2001

torhu said:

By the way, what compiler version did you use?

I used MSVC, clang and gcc (not sure of the latest versions but all recent)

I suppose if you view bool as a one-bit arithmetic type then incrementing true is an overflow and that results in undefined behaviour - so the value could be anything.

And I suppose if you incremented something N times and decremented it N times you might expect to be back where you started, which can't be guaranteed for bool so they disabled '--'.

Maybe there was some reason for it back when they wrote the spec and maybe it just slipped through the net?

[edit] The fact that it's post increment gives it one possible use, though it's not hard to find alternatives:

void printlist(int n) {
 bool comma = false;
 for (int i = 0; i < n; ++i) {
  if (comma++) {
   cout << ',';
  }
  cout << i;
 }
}

The original example was here using C++ ranged for statement which makes a bit more sense.

torhu
Member #2,727
September 2002
avatar

I really don't understand why they added a separate function for just that use case, though...

bamccaig
Member #7,536
July 2006
avatar

I'm of the opinion that if a sensible meaning can be defined for an operator then it should be. I like being able to make code terse and operators are the best way to achieve that from the language or a global library. I don't see this as a problem at all, as long as the results are defined. If anything, it's a WTF to me that you cannot decrement. It's no surprise to most of us that a boolean type is typically represented by a 0/^0/!0 byte or bit. And we all understand what the result would be of incrementing those. It may not entirely make sense logically, but at the same time a useful meaning can be applied to and derived from it.

???

Chris Katko
Member #1,881
January 2002
avatar

I suppose if you view bool as a one-bit arithmetic type then incrementing true is an overflow and that results in undefined behaviour - so the value could be anything.

But we have tons of defined overflow scenarios. Unsigned overflows, signed overflows, float overflows. It seems strange they would just leave that one alone.

My opinion--and it's about as valuable as that--is that the more things that "don't immediately make sense" the more a programmer has to keep in his mind at all times while programming. And the more balls a programmer has to juggle at once, the more likely you hit create an error.

I'm sure there's some brain function / sign-of-intelligence that corresponds to how many ideas a person can have in their brain at one time. And the more taken up by the programming language, the less available for comprehending the task at hand. Which is why many people solve complex problems outside of code... by solving the problem separated from implementing that problem, you free up some "slots" in your brain to help take a "too big to fit" problem and hopefully fit it.

Quote:

[edit] The fact that it's post increment gives it one possible use, though it's not hard to find alternatives:

Actually, have you tested for an error in that code? What happens if you increment a bool 65536 times? Does it eventually wrap a 8/16/32/64-bit integer around to zero?

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

torhu
Member #2,727
September 2002
avatar

I compiled this as C++ in VS 2015, no optimizations:

void incbool(bool b)
{
  b++;
}

And got this:

?incbool@@YAX_N@Z (void __cdecl incbool(bool)):
  00000000: 55                 push        ebp
  00000001: 8B EC              mov         ebp,esp
  00000003: 51                 push        ecx
  00000004: 8A 45 08           mov         al,byte ptr [ebp+8]
  00000007: 88 45 FF           mov         byte ptr [ebp-1],al
  0000000A: C6 45 08 01        mov         byte ptr [ebp+8],1
  0000000E: 8B E5              mov         esp,ebp
  00000010: 5D                 pop         ebp
  00000011: C3                 ret

It's just copied, and then set to true.

Elias
Member #358
May 2000

All 4 of gcc, clang, g++, clang++ produce the same asm output for C/C++ code (simply moving the value 1 into the variable). So actually C's ++ operator behaves the same on a bool as C++'s.

--
"Either help out or stop whining" - Evert

torhu
Member #2,727
September 2002
avatar

Yeah, I get get same result in VS 2015. Only the name mangling of the function changes, the assembly is otherwise identical. I guess VS finally supports C99 bool, then.

Andrei Ellman
Member #3,434
April 2003

Elias said:

Well, looking at it from C it makes sense - there bool is the same as int and anything except zero means true. So if x is 1 and you do x++ it gets 2, which is still true.

And this, boys and girls, is why you should never use bitwise operators when you should use logical operators.

Case in point:

#SelectExpand
1 2int bitmask1 = 0x02; 3int bitmask2 = 0x38; 4 5bool somefunc1(int flags) 6{ 7 return flags & bitmask1; 8} 9 10bool somefunc2(int flags) 11{ 12 return flags & bitmask2; 13} 14 15void blah(int someflags) 16{ 17 if(somefunc1(someflags) & somefunc2(someflags)) 18 { 19 // bitwise AND 20 // As long as bitmask1 and bitmask2 don't share any flags, this will never be true. 21 } 22 23 if(somefunc1(someflags) && somefunc2(someflags)) 24 { 25 // Logical AND 26 // This will be true if someflags contains at least one flag in bitmask1 and one flag in bitmask2. 27 // But in cases where we know all bools will have the same numeric value for 'true', this will be slower than a bitwise AND. 28 } 29}

Here, if bools are treated like ints, the two if()s will behave differently. However, you could create a StrictBool class that behaves like a bool should. All operators will be overloaded with versions that use C++'s 'explicit' keyword with StrictBool-paramaters to prevent implicit casting, and there will be non-explicit versions of the operators that for each paramater, regardless of it's type, do something like value = (paramater?true:false) . In this case, both if()'s in the above code will be equivalent if the functions return StrictBools.

--
Don't let the illegitimates turn you into carbon.

torhu
Member #2,727
September 2002
avatar

Yeah ;D

{"name":"636x460design_01.jpg","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/4\/8\/48bed991ae72aac26032315a4ba6c62b.jpg","w":636,"h":460,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/4\/8\/48bed991ae72aac26032315a4ba6c62b"}636x460design_01.jpg

Mark Oates
Member #1,146
March 2001
avatar

I ran some rudimentary (uncomprehensive) tests for performance between either several bool types or bitwise on an int.

Bitwise was a bit slower.

...

:D

No, but actually it was a bit slower. Only by about ~7% or something, though.

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

torhu
Member #2,727
September 2002
avatar

You should be careful with that kind of thing. Many simple operations require only one cycle on the CPU to do. And if you are comparing ints to bools on a PC (32 or 64 bits), you are probably comparing 32-bit types to 8-bit types. Which one is faster depends on what you do with. You could be comparing an operation to one that's different in either implementation, purpose, or both. Just saying :P

Bruce Perry
Member #270
April 2000

Isn't it the case that the compiler ensures that bools always have a 0 or a 1 stored in their memory location?

I think Visual Studio warns if an int is implicitly cast to bool, and the wording of the warning suggests that there will be a performance hit from the operation of constraining its value.

--
Bruce "entheh" Perry [ Web site | DUMB | Set Up Us The Bomb !!! | Balls ]
Programming should be fun. That's why I hate C and C++.
The brxybrytl has you.

Mark Oates
Member #1,146
March 2001
avatar

Since ++ just copies it and sets it to true, then there's no reason not to include -- to copy and set to false.

Note: my actual position is that the operators should not be used at all on bool.

torhu said:

You should be careful with that kind of thing. Many simple operations require only one cycle on the CPU to do. And if you are comparing ints to bools on a PC (32 or 64 bits), you are probably comparing 32-bit types to 8-bit types. Which one is faster depends on what you do with. You could be comparing an operation to one that's different in either implementation, purpose, or both. Just saying :P

All of that's probably true :P

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

Arthur Kalliokoski
Second in Command
February 2005
avatar

Since ++ just copies it and sets it to true, then there's no reason not to include -- to copy and set to false.

It doesn't even need to copy, just set.

They all watch too much MSNBC... they get ideas.

torhu
Member #2,727
September 2002
avatar

It has to copy, that's the whole point of postincrement.

Fuck Matthew Leverton, just fuck him.

 1   2 


Go to: