![]() |
|
This thread is locked; no one can reply to it.
![]() ![]() |
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. 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
![]() |
WHAT? I thought for sure (bool)++ was negate. This is like Javascript-level stupidity. 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: |
torhu
Member #2,727
September 2002
![]() |
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 |
Chris Katko
Member #1,881
January 2002
![]() |
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: |
torhu
Member #2,727
September 2002
![]() |
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
![]() |
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 -- |
Chris Katko
Member #1,881
January 2002
![]() |
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: |
Mark Oates
Member #1,146
March 2001
![]() |
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. |
Arthur Kalliokoski
Second in Command
February 2005
![]() |
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
![]() |
I really don't understand why they added a separate function for just that use case, though... |
bamccaig
Member #7,536
July 2006
![]() |
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.
-- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Chris Katko
Member #1,881
January 2002
![]() |
Peter Hull said: 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: |
torhu
Member #2,727
September 2002
![]() |
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. -- |
torhu
Member #2,727
September 2002
![]() |
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: 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. -- |
torhu
Member #2,727
September 2002
![]() |
Yeah {"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"} |
Mark Oates
Member #1,146
March 2001
![]() |
I ran some rudimentary (uncomprehensive) tests for performance between either several bool types or bitwise on an int. Bitwise was a bit slower. ... No, but actually it was a bit slower. Only by about ~7% or something, though.
|
torhu
Member #2,727
September 2002
![]() |
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 |
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. -- |
Mark Oates
Member #1,146
March 2001
![]() |
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 All of that's probably true |
Arthur Kalliokoski
Second in Command
February 2005
![]() |
Mark Oates said: 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
![]() |
It has to copy, that's the whole point of postincrement. Fuck Matthew Leverton, just fuck him. |
|
1
2
|