By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,171 Members | 1,020 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,171 IT Pros & Developers. It's quick & easy.

bitwise not and "auto casts"

P: n/a
When the bitwise NOT operator, is placed in front of an integer
variable type (bool, char, short, int, long), the return value is a
signed int, regardless of the variable type. An example can be seen
in this code:

#include<iostream>

using namespace std;

int main(){
bool a = true;
bool b = !a;
cout << hex
<< a << endl // 1
<< b << endl // 0
<< ~a << endl // fffffffe
<< dec
<< ~a << endl // -2
<< hex
<< ~~a << endl // 1
<< ~~~a << endl; // fffffffe

cin.get();
return 0;
}

This doesn't see right...a bool that's been bit-notted *should* return
a single bit instead of returning 32-bits!! The same applies to a
bit-notted char...one would expect 8-bits in return.
Any comments
Jul 19 '05 #1
Share this Question
Share on Google+
8 Replies


P: n/a

"J. Campbell" <ma**********@yahoo.com> wrote in message news:b9**************************@posting.google.c om...
When the bitwise NOT operator, is placed in front of an integer
variable type (bool, char, short, int, long), the return value is a
signed int, regardless of the variable type.


It is not. The type is the promoted type of the operand. It's not necessarily
a signed int. If you applied it to an unsigned, the result would be unsigned.

Bool however is promoted, just as it is for the rest of the mathematical operators.
Same thing happens with char, etc...

That's just the way C and C++ do their math.

Jul 19 '05 #2

P: n/a
"Ron Natalie" <ro*@sensor.com> wrote in message news:<3f***********************@news.newshosting.c om>...
"J. Campbell" <ma**********@yahoo.com> wrote in message news:b9**************************@posting.google.c om...
When the bitwise NOT operator, is placed in front of an integer
variable type (bool, char, short, int, long), the return value is a
signed int, regardless of the variable type.
It is not. The type is the promoted type of the operand. It's not necessarily
a signed int. If you applied it to an unsigned, the result would be unsigned.


This actually is not true with my C++ compiler. In this example, the
signed int, -2 is returned for (not 1) for bool, char, and unsigned
char. If you print the hex, you will see that it's FFFFFFFE...clearly
(~variable) returns an unsigned int regardless of variable's type.

#include<iostream>
using namespace std;
int main(){
bool a = true;
unsigned char b = 1;
signed char c = 1;
cout << ~a << endl // -2
<< ~b << endl // -2
<< ~c << endl; // -2
cin.get();
return 0;
}

And in this example, bit notting a bool returns the same initial
value!!!

#include<iostream>
using namespace std;
int main(){
bool a = 1;
bool b = ~a;
if (a == b)
cout << "imagine that, b = not a, yet a == b!!!\n";
cin.get();
return 0;
}


Bool however is promoted, just as it is for the rest of the mathematical operators.
Same thing happens with char, etc...

That's just the way C and C++ do their math.


Yep...it just seems a little nonsensical that a notted bool can return
-2...when the only possible values for a bool are 1 and 0.

I do understand though...C++ takes the value and padds with leading
zeros then does the logic on that native-length int...and returns that
value. However, in this last example where b is assigned ~a, yet b
still evaluates equal to a...this seems like an example where the c++
treatment is a poor choice. Again, I understand why it evaluates this
way...bool a = 1, ~a == fffffffe, bool b = ~a, fffffffe != 0,
therefore b == true == 1. However this does not follow any kind of
natural boolean logic. if bool a = 1, then not a should evaluate to
0, with no if's ands or buts. I realize that this behavior can be had
using the logical not rather than the bitwise not...but I still don't
like it.

My old language had a similar problem. It boiled down to something
like this...

int a = 10. int b = not a. yet a and b both evaluate to true. This
is easy to understand because both a and b hold non-zero values,
therefore both true. But with a bool type, a and not a should never
both contain non-zero values!!!

Thanks for the response.
Jul 19 '05 #3

P: n/a

"J. Campbell" <ma**********@yahoo.com> wrote in message news:b9*************************@posting.google.co m...
"Ron Natalie" <ro*@sensor.com> wrote in message news:<3f***********************@news.newshosting.c om>...
"J. Campbell" <ma**********@yahoo.com> wrote in message news:b9**************************@posting.google.c om...
When the bitwise NOT operator, is placed in front of an integer
variable type (bool, char, short, int, long), the return value is a
signed int, regardless of the variable type.


It is not. The type is the promoted type of the operand. It's not necessarily
a signed int. If you applied it to an unsigned, the result would be unsigned.


This actually is not true with my C++ compiler. In this example, the
signed int, -2 is returned for (not 1) for bool, char, and unsigned
char. If you print the hex, you will see that it's FFFFFFFE...clearly
(~variable) returns an unsigned int regardless of variable's type.


No your tests are flawed. ostreams encoders are lousy things for determining
the TYPE of the object. Try typeid or using something that overloads over the
types you are trying to differentiate. The hex formatter always prints the number
as unsigned no matter what the input type is:

int i = -1
cout << hex << i << endl; // prints ffffffff

Second a math lesson: ~1 as a signed integer is -2, ~0 is -1 if you machine uses
2's complement math (as most do).

What happens when you apply ~ to a integral type is that the types are promoted
(as they are for the other math and bitwise operators). The following is straight
from 4.5 of the standard.

An rvalue of type char, signed char, unsigned char, short int, or unsigned short
int can be converted to an rvalue of type int if int can represent all the values of the source type; other-wise,
the source rvalue can be converted to an rvalue of type unsigned int.
An rvalue of type bool can be converted to an rvalue of type int, with false becoming zero and true
becoming one.

Thus all the type conversion that you are observing happens prior to the ~ being applied.
The result of ~ is the promoted (from above) type of the argument.

None of your tests show otherwise.
Jul 19 '05 #4

P: n/a
hi!
If you print the hex, you will see that it's FFFFFFFE...clearly
(~variable) returns an unsigned int regardless of variable's type. ?? if the result of bit-inverting 1 is -2 then the result is not
unsigned!!?!
clearly if the MSB is 0 (positive int 2-complement) its inverted to 1
(negative)
and the other way round.
However this does not follow any kind of
natural boolean logic.

bitwise negation is not an operation of boolean logic, isn't it??? use !
instead,...

regards,
sev
Jul 19 '05 #5

P: n/a
"Severin Ecker" <se****@gmx.at> wrote in message news:<3f***********************@aconews.univie.ac. at>...
hi!
If you print the hex, you will see that it's FFFFFFFE...clearly
(~variable) returns an unsigned int regardless of variable's type. ?? if the result of bit-inverting 1 is -2 then the result is not
unsigned!!?!


Yes...I meant signed.
clearly if the MSB is 0 (positive int 2-complement) its inverted to 1
(negative)
and the other way round.

I understood where the -2 came from...my point was just that, for a
1-bit integer number, it's not value should also be a 1-bit number.
However this does not follow any kind of
natural boolean logic.

bitwise negation is not an operation of boolean logic, isn't it??? use !
instead,...


indeed...this is what I've done
regards,
sev


Thanks for the reply.
Jul 19 '05 #6

P: n/a
"Ron Natalie" <ro*@sensor.com> wrote:
The following is straight
from 4.5 of the standard.

An rvalue of type char, signed char, unsigned char, short int, or unsigned short
int can be converted to an rvalue of type int if int can represent all the values of the source type; other-wise,
the source rvalue can be converted to an rvalue of type unsigned int.
An rvalue of type bool can be converted to an rvalue of type int, with false becoming zero and true
becoming one.

Thanks Ron...this was my "discovery". I think this behavior is odd,
although I can understand and predict the output once it's understood.

In either case, you seemed to be insulted by my first reply to
you...no insult was intended.

I still think that the output from this code is not at all
intuitive...

#include<iostream>
using namespace std;
int main(){
bool a = 1;
bool b = ~a;
if (a == b)
cout << "imagine that, b = not a, yet a == b!!!\n";
cin.get();
return 0;
}

Output:
imagine that, b = not a, yet a == b!!!

I'd hazard a guess that many c++ programmers who consider theselves
competent would incorrectly predict the output of this program.

Joe (a not yet competent c++ programmer) ;-)
Jul 19 '05 #7

P: n/a

"J. Campbell" <ma**********@yahoo.com> wrote in message news:b9**************************@posting.google.c om...
I'd hazard a guess that many c++ programmers who consider theselves
competent would incorrectly predict the output of this program.


I don't know why. C and C++ has always promoted char's, why would bools
be any different. bools are never implmeneted as one bit storage anyhow because
they can't be smaller than char.
Jul 19 '05 #8

P: n/a
"Ron Natalie" <ro*@sensor.com> wrote in message news:<3f***********************@news.newshosting.c om>...
"J. Campbell" <ma**********@yahoo.com> wrote in message news:b9**************************@posting.google.c om...
I'd hazard a guess that many c++ programmers who consider theselves
competent would incorrectly predict the output of this program.


I don't know why. C and C++ has always promoted char's, why would bools
be any different. bools are never implmeneted as one bit storage anyhow because
they can't be smaller than char.


Fair enough...that's why I signed off as a "non-competent c++
programmer". Cheers, and thanks for the pointer to the reference that
clarifies the (non)issue I raised.

Cheers.
Jul 19 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.