Checked and Unchecked Keywords in C#

Description

The checked and unchecked keywords in C# can help to detect/prevent overflows.

The checked keyword is used to check for overflows in arithmetic operations. By default, the compiler will detect overflows but only if constant values will exceed the size of the used type. If variables instead of constants are used, the compiler won’t detect the overflow and won’t generate an error.

The unchecked keyword is used to suppress overflow checking in arithmetic operations. In an unchecked context, even if two or more constants would exceed the type’s size, the overflow will not be signaled at compile time by an error.

Usage

Let’s see the following scenario:

int maxValue = int.MaxValue; //2147483647
int overflow = int.MaxValue + 10; //flagged at compile time (constants)
int overflow = maxValue + 10; //-2147483639 - legal (variables)

By default, there is no overflow checking so the last statement is legal, producing the -2147483639 value which probably is unexpected.

With checked keyword:

int maxValue = int.MaxValue; //2147483647            
int overflow = checked(maxValue + 10); //OverflowException thrown

With unchecked keyword:

int maxValue = int.MaxValue; //2147483647            
//note the usage of constants
int overflow = unchecked(int.MaxValue + 10); //legal, value is -2147483639

Both declaration styles are correct and equivalent:

int maxValue = int.MaxValue; //2147483647 

int overflow = checked(maxValue + 10);

checked
{
    int overflow = maxValue + 10;
}
int maxValue = int.MaxValue; //2147483647 

int overflow = unchecked(maxValue + 10);

unchecked
{
    int overflow = maxValue + 10;
}

Checking for overflows takes time. In more complex situations of overflow checking, you might want to use the unchecked keyword to improve performance within the checked block like so:

checked
{
    //code to check for overflows
    unchecked
    {
       //code you know it can't overflow so the check can be skipped
    }
}

Unchecks in this case are used to break out from the check blocks to improve performance.

Keep in mind that if performance improvements are not worthy, generally (not just in this situation) it’s usually a bad idea to perform this kind of “optimizations”.

Conclusion

Checking for overflow takes time. In case overflow is a possibility, the checked keyword should be used.

The unchecked keyword should only be used where there is no danger in running into an overflow.

Advertisements

Assertions vs UnitTest Assertions

Description

I recently found out that there are two types of assertions we can use: there is the popular unit test Assert and then there is the “normal” Assert which is used in debug/production code.

Whenever I heard the term Assertion, I immediately thought about unit testing, checking the test’s condition to determine whether the unit test passed or not.

The “normal” assertion was kind of new to me. I knew the concept, but I didn’t imagine it could be used in everyday debug/production code. However, this is a pretty cool feature (at first glance at least :)). I don’t know why isn’t it more popular or why most people don’t use it. I haven’t seen any assertions in the debug/production code I worked with in my (limited) roughly 5 years experience in software development.

Usage

As I’ve said, we can use assertions in both debug and production code.
By debug code I am referring to the not released code, which is still under development.
By production code I am referring to a code which has been released, is live and used on different systems in production.

We have two classes which can be used for the above mentioned cases, both classes are under the System.Diagnostics namespace.

Debug.Assert(bool) – used to check different conditions. If the condition is true, nothing special happens, otherwise the code execution is stopped and an Assertion Failed error message is usually displayed (for GUI applications only). Once the error message is displayed, we have three options:

  • abort – which causes the code to execution to stop;
  • retry – which will allow the developer to get into debug mode right on that assert;
  • ignore – which ignores the failed assertion and continues with the code execution.

The Assert method has two more overloads: Debug.Assert(bool, string) and Debug.Assert(bool, string, string). The string parameters can be filled in to display one or two messages when the assertion fails in the Assertion Failed error message.

Debug.Assert will only be executed when the code is compiled under Debug configuration. Since it won’t be included in the Release, it can be used without any restrictions while developing to catch odd cases which may be not  covered by the unit tests. It’s perfect for the cases when the code crashes randomly because the developer can jump into debug mode and identify what’s going on.

Assertion Failed with two messages
Assertion Failed with two messages

Trace.Assert(bool), Trace.Assert(bool, string), Trace.Assert(bool, string, string) is the same  as Debug.Assert the only difference being that Trace.Assert is used for Release builds (code compiled under Release configuration). The Trace.Assert also works in debug configuration, but it was designed to be used in Release builds. 

Assertions vs. Exception Throwing

You might think why on earth would I complicate things by using these assertions when I could be throwing exceptions in the wired cases. To understand why using assertions is better, you have to know the difference between assertions and exceptions.

Assertions stop the code execution when the assert condition fails.

Exceptions can be thrown and caught, allowing the code to continue execution. 

Exceptions were designed to be caught and handled. That’s why you catch an exception, to handle it and allow the code to continue its execution. Assertions on the other hand are designed to validate that the  received data is valid so the whole program does not enter a corrupted state. Usually, when the data you receive is corrupt, the whole program can be corrupted as well and this is a case we want to avoid at all costs. Breaking the code execution the moment our data is corrupt would be the best approach in preserving our program’s state corruption free.

Conclusion

You want to use Assertions to check for corrupted data or for weird cases which shouldn’t happen (situations which cannot arise during the software’s normal operations) and for which there is nothing to be done in order for the program to continue its execution (ex: division by zero).

You want to throw and catch exceptions for the cases where you can actually do something about the exception (situations which arise during the software’s normal operations) and the code execution may have a chance to continue its execution (for example if a null reference is encountered, you could instantiate that object).

Like a fellow on stackoverflow said:

It should ALWAYS be possible to produce a test case which exercises a given throw statement. If it is not possible to produce such a test case then you have a code path in your program which never executes, and it should be removed as dead code.

It should NEVER be possible to produce a test case which causes an assertion to fire. If an assertion fires, either the code is wrong or the assertion is wrong; either way, something needs to change in the code.

Related:

Both Debug and Trace classes also expose other methods such as Write, WriteIf, WriteLine, WriteLineIf which can be used to log certain errors using TraceListeners, but this is another discussion for a future post.

A simmilar concept which will have a dedicated post in the near future is Code Contracts and asserting pre and postconditions.

Hello World

This is my first blog post. Ever.

Even though I (used to) find keeping a blog: lame, pointless, worthless, time-consuming, tedious, just to show-off with shitty content, I came to realize that this thing could be used for another practical purpose for myself.

I work as a .NET software developer and I’m trying to become a better programmer. To do this, I started reading various books in order to gather all the information I can. The problem is that I tend to lose my reading notes and/or not have them organized, easy to find, self-explanatory with examples. Thus, it’s harder for me to remember important details about a topic by reading my notes, because they are too “sketchy” or I don’t have them at all.

Then it hit me: I could use a blog to write all my book notes in a clean, organized, detailed and explanatory way so I can easily access the information later on. Since I am making my posts public (although I doubt anybody except myself will read this 🙂 ) I kinda force myself into writing the notes more structured, clear, with enough details to make myself understood at the first read.

Furthermore, I am not a native English speaker (or writer :)), so this way I get to practice my written English some more. So, this blog actually helps me twice as much.

It’s kinda late, and instead of focusing on my actual notes, I’ve lost some 15 minutes writing this useless text (one of my first thoughts – pointlessness). I hope for this to change in the future. I now need to find a nice theme to support clean code-posing for the blog.

Nite?