what are the unary values for unary boolean operators

Dec 14, 2012 at 8:24pm
I am implementing boolean operator overloads and have some strange results for unary operators. My code shows that in gcc 4.5.3:
1
2
3
4
5
6
7
8
                         expections
   actual results        true  false
!true  = !false ==  0      0     1   (logical not of value)
~true  = ~false == -2    0xFE  0xFF  (binary  not of value)
+true  = +false ==  1                (depends if bool is an int or bool)
++true = ++false == 1                (if bool then illegal otherwise ++int)
true++ = false++ == 1                (same as above)
--true = -- false == NOT ALLOWED     (legal and treating like bool++)


Where some values depend on whether the boolean input is treated as a bool (with values true|false), or an int (with values 0|1). If it treated as a boolean then I would expect the results to be a boolean (true|false) or within the range of a boolean treated as an int (0|1).

The results are unexpected and appear wrong. Is my code wrong, gcc at fault, or my understanding faulty? Any help is appreciated.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# include <iostream>
# include "cstdio"
# include <cstdlib>

using namespace std;
void func0(bool x) {
   string xStr = (x)? "true": "false";
   cout << "func0(" << xStr << ')' << endl
        << "!x  " << (!x)  << endl
        << "~x  " << (~x)  << endl
        << "+x  " << (+x)  << endl
        << "-x  " << (-x)  << endl
        << "++x " << (++x) << endl
        << "--x " << "error" << endl
        << "x++ " << (x++) << endl
        << "x-- " << "error" << endl
        << endl;
   
}
void func1(bool x, bool y) {
   string xStr = (x)? "true": "false";
   string yStr = (y)? "true": "false";
   cout << "func1(" << xStr << ", " << yStr << ')' << endl
        << "x + y " << (x + y) << endl
        << "x - y " << (x - y) << endl
        << "x * y " << (x * y) << endl;
   if (y == 0) {
        cout << "x / y " << x << " / 0" << endl;
   } else {
        cout << "x / y " << (x / y) << endl;
   }
}
void func2(bool x, int y) {
   string xStr = (x)? "true": "false";
   char buf[10];
   sprintf(buf, "%i", y);
   string yStr(buf);
   cout <<"func2("  << xStr << ", " << yStr << ')' << endl
        << "x + y " << (x + y) << endl
        << "x - y " << (x * y) << endl
        << "x / y " << (x / y) << endl;
   cout << yStr << ", " << xStr << endl
        << "y + x " << (y + x) << endl
        << "y - x " << (y - x) << endl
        << "y * x " << (y * x) << endl;
   if (x == 0) {
      cout << "y / x " << y << " / 0" << endl;
   } else {
      cout << "y * x " << (y / x) << endl;
   }
}
int main(int argc, char** argv) {
   bool x = false;
   func0(true);
   func0(false);
   
   func1(true, true);
   func1(true, false);
   func1(false, true);
   func1(false, false);

   func2(true, 1);
   func2(false, 1);
   return 0;
}
Dec 14, 2012 at 8:49pm
Your expectations appear to be different from how C++ defines the results of those operations, but your code is also very wrong: your func0() output statement invokes undefined behavior because it attempts to modify (via opeator++) and access (many times) the same object without any sequencing.

Note that ++ for bools is a bizarre anachronism, it was deprecated the moment it was inherited from C, and will likely be removed from the language soon.
Last edited on Dec 14, 2012 at 8:50pm
Dec 14, 2012 at 10:16pm
Thanks for the update on the outlandish ++.

I don't understand your comments on func0() having undefined output behavior. Could you elaborate?

When I coded I thought I'd done just fine (sigh). Except of X++ and ++X, each statement presents the result of a computation without altering the value of the variable, and I assumed the variable was then immediately available for a subsequent operation. I don't see the issue.
Dec 14, 2012 at 10:33pm
I don't understand your comments on func0() having undefined output behavior. Could you elaborate?

The expression cout << x << ++x is UB (if x is of a non-class type) because it attempts to modify x and read from x on independent, unsequenced code paths.
There are some details here: http://en.cppreference.com/w/cpp/language/eval_order

g++ -Wall describes it as
test.cc:17:16: warning: operation on ‘x’ may be undefined [-Wsequence-point]


Put a semicolon before the first cout << (++x), and the output of your func0() will make more sense.
Last edited on Dec 14, 2012 at 10:33pm
Dec 15, 2012 at 12:22am
unary means that i only requires one operand
binary means that it only requires 2
tertary means 4
and so on.
Topic archived. No new replies allowed.