Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
692 views
in Technique[技术] by (71.8m points)

c# - Why should I explicitly surround with "unchecked"?

Is there anyone able to explain me this strange behavior?

    int i = 0x1234;
    byte b1 = (byte)i;
    byte b2 = (byte)0x1234;         //error: const value '4660' can't convert to byte (use unchecked)
    byte b3 = unchecked((byte)0x1234);
    byte b4 = checked((byte)i);     //throws
    byte b5 = (byte)(int)0x1234;    //error: same as above

NOTE: It's an empty Console application, with NO arithmetic checking enabled (as default is). Thank you everybody in advance.

EDIT: I supposed to be clear enough, but not for all.

I do know that a word can't fit into a byte. But, by default, a C# program allows certain "dangerous" operations, primarily for performance reason.

Similarly, I may sum two large integers together and having no overflow at all.

My wonder was about the compile-time error above: the b1 cast/assignment is compiled, the b2 can't compile. Apparently there's no difference, because both are Int32 having the same value.

Hope it's clear now.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You're tripping over a part of section 7.19 of the C# 4 spec:

Unless a constant expression is explicitly placed in an unchecked context, overflows that occur in integral-type arithmetic operations and conversions during the compile-time evaluation of the expression always cause compile-time errors.

Basically, the point is that even if you're happy to allow operations to overflow at execution time, if you're trying to use a constant expression which can't be converted to the target type at compile time, you have to tell the compiler that you really know what you're doing.

For example, in this case you're losing information - it'll be equivalent to

byte b3 = 0x34;

so you'd normally be better off just specifying that, to give you clearer code which doesn't mislead the reader. It's relatively rare that you want to overflow in a constant - most of the time you should just specify the valid value instead.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...