unchecked() and Bitwise Operations after Promotion

J

Jeffrey Walton

Hi All,

What is wrong with the following? C# claims:
"An unhandled exception of type 'System.OverflowException' occurred in
mscorlib.dll Additional information: Value was either too large or too
small for an unsigned byte."

The offending code is:

// vector< byte >
ArrayList Octets = new ArrayList();
....
Int32 i=0;
while( i < Octets.Count )
{
Byte b = Byte.Parse(Octets.ToString());
b &= unchecked(Convert.ToByte(~0x80)); // Problem Here

if( 0x00 == b ) { break; }

....

i++;
}

Frow what I understand, 0x80 is an Int32. operator~ gives me a 32 bit
compliment. unchcked turns off overflow checking, so the cast to a
Byte should work (without overflow complaints)...

Jeff
Jeffrey Walton
 
J

Jeffrey Walton

Hi All,

Forgot to mention... I want to do is check if the high bit is set on
an octet. Sorry about all the extra code. C# does not appear to be
built for byte parsing, such as encountered with ASN.1 parsing.

Jeff
 
P

Peter Duniho

[...]
Frow what I understand, 0x80 is an Int32. operator~ gives me a 32 bit
compliment. unchcked turns off overflow checking, so the cast to a
Byte should work (without overflow complaints)...

I try not to bypass the compiler when at all possible, so I might be
missing something here, but...

I believe "unchecked" applies to the _result_ of Convert.ToByte(). The
call to ToByte() itself isn't changed, and of course fails because the
parameter is too large for a byte.

Why can't you just write someting like this:

b &= 0x7f;

or if you really want the ~0x80:

b &= (byte)(~0x80 & 0xff);

or even better, stop messing with b altogther:

if ((b & 0x7f) == 0) { break; }

without the &= line.

I don't see the need to call Convert.ToByte() at all.

Pete
 
J

Jon Skeet [C# MVP]

Frow what I understand, 0x80 is an Int32. operator~ gives me a 32 bit
compliment. unchcked turns off overflow checking, so the cast to a
Byte should work (without overflow complaints)...

That would be the case if you were *casting* to a byte - but you're
not, you're calling a method: Convert.ToByte.

Change the code to:

b &= unchecked((byte)~0x80);

and it'll be fine.

Are you actually in a checked context to start with though? C# is
unchecked by default anyway.
 
J

Jeffrey Walton

Hi John,

Operator Error. I was not aware the compiler would treat 0x80 as an
integer when the variable operand was a byte. I would have been nice
if it would have demoted for me also.

Add to it the fact that the compliment operator only works on data
types of int and larger, and I'm totally confused.

Jeff
 
J

Jeffrey Walton

Hi Pete,

Operator Error. I was not aware the compiler would treat 0x80 as an
integer when the variable operand was a byte. It would have been nice
if it would have demoted for me also.

Add to it the fact that the compliment operator only works on data
types of int and larger, and I'm totally confused.

Jeff

[...]
Frow what I understand, 0x80 is an Int32. operator~ gives me a 32 bit
compliment. unchcked turns off overflow checking, so the cast to a
Byte should work (without overflow complaints)...

I try not to bypass the compiler when at all possible, so I might be
missing something here, but...

I believe "unchecked" applies to the _result_ of Convert.ToByte(). The
call to ToByte() itself isn't changed, and of course fails because the
parameter is too large for a byte.

Why can't you just write someting like this:

b &= 0x7f;

or if you really want the ~0x80:

b &= (byte)(~0x80 & 0xff);

or even better, stop messing with b altogther:

if ((b & 0x7f) == 0) { break; }

without the &= line.

I don't see the need to call Convert.ToByte() at all.

Pete
 
Top