2

The MSDN examples are just compile time errors.

It's just I see @JonSkeet uses it an answer here: https://stackoverflow.com/a/263416/360211 and I can't see why if it's just compile time.

    static void Main()
    {
        const int x = 4;
        int y = int.MaxValue;
        int z = x*y;
        Console.WriteLine(z);
        Console.ReadLine();
    }

Produces -4, same as this:

    static void Main()
    {
        unchecked
        {
            const int x = 4;
            const int y = int.MaxValue;
            int z = x*y; // without unchecked, this is compile error
            Console.WriteLine(z);
            Console.ReadLine();
        }
    }

This throws runtime:

    static void Main()
    {
        checked
        {
            const int x = 4;
            int y = int.MaxValue;
            int z = x*y; //run time error, can checked be set system wide?
            Console.WriteLine(z);
            Console.ReadLine();
        }
    }

So is Jon doing this because it could be set system wide, compiler flag or otherwise?

Community
  • 1
  • 1
weston
  • 54,145
  • 21
  • 145
  • 203
  • Your `y` is `const` in the unchecked code and not in the checked code. If it was `const` in the checked code, it would throw a compile-time error. – Bobson Nov 16 '12 at 16:02
  • @Bobson yes was deliberate to show the difference. – weston Nov 16 '12 at 16:10
  • Used this to improve my hash code builder helper class http://stackoverflow.com/a/10634833/360211 – weston Nov 16 '12 at 16:20

3 Answers3

1

Absolutely not. It determines whether an exception (OverflowException) is thrown at execution time if an operation overflows.

For example, in Noda Time we perform almost all our arithmetic in a checked context (it's the project default). However, for hash codes we always use an unchecked block, as it's absolutely fine for hash code computations to overflow - the magnitude of the value doesn't really matter; overflow won't affect correctness.

It's only relevant at compile-time for operations that the compiler can know will overflow due to involving constant values.

See section 7.6.12 of the C# 4 specification for more details.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
1

Whether an operation is in a checked or unchecked block is executed when the values are actually computed. When multiplying/adding two variables this will almost always be at runtime, since they aren't known at compile time.

In your example the two variables are both constants; this means that the result of the computation between compile time literals can be done at compile time (which it is). Since the result is being computed at compile time, and it's not in an unchecked block, it can't compute the result without an error. That does not mean that checked/unchecked blocks are generally a compile time check; they very rarely are.

And yes, it is possible to change the project properties for whether the entire code base is in a checked/unchecked context. If you're writing a library it's also possible for the method to be called from within either context. For that reason, if there's a block of code that must run in either a checked or unchecked context it's a good practice to add such a block, even if your current project setting is correct for that method. Also, if nothing else, it's making the intent of that snippet clearer to future readers, "This method relies on integer overflow," vs., "This method must never overflow."

Servy
  • 202,030
  • 26
  • 332
  • 449
  • Given to you because of the "... possible for the method to be called from within either context" So it's more than just a project wide setting consideration problem. – weston Nov 16 '12 at 16:19
0

Set the default behaviour for neither checked or unchecked code by going to:

Project properties->Build->Advanced->Check for arithmetic overflow/underflow

Default for new projects is off, which is why I assumed unchecked had no run time effect.

weston
  • 54,145
  • 21
  • 145
  • 203