I am accustomed to C# not performing overflow checks, as the language spec states (ยง7.5.12):
For non-constant expressions (expressions that are evaluated at run-time) that are not enclosed by any checked or unchecked operators or statements, the default overflow checking context is unchecked unless external factors (such as compiler switches and execution environment configuration) call for checked evaluation.
I took advantage of this when doing an array bounds check in low-level code:
if ((uint)index >= (uint)TotalCount)
...
If index is negative, I expect it to become a large positive number so that it exceeds TotalCount. However, to my surprise, a negative number produces OverflowException, and I have to wrap the expression in unchecked(). I looked through the project options in Visual Studio and I do not see an option to enable or disable overflow checking. So why might it be on here?
It should be in the project.
Double click the Properties folder.
Build tab.
Click the Advanced... button.
Uncheck "Check for arithmetic overflow/underflow".
Related
Code in C#:
address = glowObject + (glowIndex * 0x38) + 0x4;
Code in VB:
address = glowObject + (glowIndex * &H38) + &H4
I inserted a breakpoint on that line in both my C# code and VB code.
The values were the same in both.
C#: Breakpoint:
VB Breakpoint:
So it looks like my VB code is getting the result, but it's still throwing an exception on that line of code.
What could be causing this?
In C#, arithmetic operations are unchecked by default, which means that arithmetic overflow is not checked at runtime. You can control this with the checked/unchecked keywords, and/or with the /checked compiler option.
In VB.NET, arithmetic operations are checked by default.
In your code, the result overflows the capacity of an int; in C#, it overflows silently, producing an incorrect result, whereas in VB.NET, it throws an exception. In either case, your code has a bug...
Found the solution :)
It was as simple as checking a box in the compiler options.
Thank you to Thomas Levesque for telling me about the compiler option.
Go to the compile tab in your project settings, click on Advanced Compiler Settings, and check the "Remove integer overflow checks"
I was tinkering with IP packet 'parsers' when I noticed something odd.
When it came to parsing the IP addresses, in C#
private uint srcAddress;
// stuff
srcAddress = (uint)(binaryReader.ReadInt32());
does the trick, so you'd think this VB.Net equivallent
Private srcAddress As UInteger
'' stuff
srcAddress = CUInt(binaryReader.ReadInt32())
would do the trick too. It doesn't. This :
srcAddress = reader.ReadUInt32()
however will.
Took some time to discover, but what have I dicovered -- if anything ? Why is this ?
VB.NET, by default, does something that C# doesn't do by default. It always check for numerical overflow. And that will trigger in your code, IP addresses whose last bit is 1 instead of 0 will produce a negative number and that cannot be converted to UInteger. A data type that can only store positive 32-bit numbers.
C# has this option too, you'd have to explicitly use the checked keyword in your code. Or use the same option that VB.NET projects have turned on by default: Project + Properties, Build tab, Advanced, tick the "Check for arithmetic overflow/underflow" checkbox. The same option in VB.NET project is named "Remove integer overflow checks", off by default.
Do note how these defaults affected the syntax of the languages as well. In C# you have to write a cast to convert a value to an incompatible value type. Not necessary in VB.NET, the runtime check keeps you out of trouble. It is very bad kind of trouble to have, overflow can produce drastically bad results. Not in your case, that happens, an IP address really is an unsigned number.
Do keep the other quirk about IP-addresses in mind, sockets were first invented on Unix machines that were powered by LSD and big-endian processors. You must generally use IPAddress.NetworkToHostOrder() to get the address in the proper order. Which only has overloads that take a signed integer type as the argument. So using ReadInt32() is actually correct, assuming it is an IPv4 address, you pass that directly to NetworkToHostOrder(). No fear of overflow.
I have made a calculator with C# (in VS 2008), but I can't understand why the
checked{iCurrent = (iCurrent * 10) + i;}
can check the overflow, can someone explain this? Thanks.
This is my code:
try
{
//get the typed
long iCurrent=long.Parse(textOut.Text);
if(bNumBegins)
{
iCurrent = i;
bNumBegins = false;
}
else
{
//check whether overflow
checked{iCurrent = (iCurrent * 10) + i;}
}
textOut.Text = iCurrent.ToString();
}
When you use the checked keyword you ask the compiler to automatically generate code that will test whether overflow has occurred after arithmetic operations. If overflow is detected, an OverflowException is thrown.
The default in C# is to not check for such overflow when performing arithmetic operations. The default can be changed to check all operations. Regardless of the default, the checked and unchecked keywords can be used to selectively check or ignore overflow as needed.
#DavidPilkington Yes, why need * 10? Thanks
I think that you are confused here.
The code is multiplying the iCurrent variable by 10 and then adding one. This is the desired effect that the coder wanted. The checked keyword is used to make sure that there is no OverflowException.
The *10 is not needed for the checked, the check is "needed" for the operation to ensure that the number is not too large.
Here is the MSDN documention on checked. I suggest you read through it and the examples to gain a better understanding.
I am working on a calculation module using C#, and I bumped on this :
double v = 4 / 100;
I know this is a wrong initialization that returns v = 0.0 instead of v = 0.04
The c# rules says I must ensure at least one of the member is a double, like this :
double v = (double) 4 / 100;
double v = 4.0 / 100;
However, I have many many initializations of that kind that involves integer variables operations, and I feel lazy to browse my code line by line to detect such mistakes.
Instead, is it possible to get warned by the compiler about this ?
Alright, after some playing around and what not, I have a solution. I used this article to come to this solution.I use StyleCop, so you'll need to get and install that. Then, you can download my C# project MathematicsAnalyzer.
First off, I did not account for all type conversion mismatches. In fact, I only accommodate one part.
Basically, I check to see if the line contains "double" followed by a space. I do know that could lead to false warnings, because the end of a class could be double or any number of other things, but I'll leave that to you to figure out how to properly isolate the type.
If a match is found, I check to see that it matches this regex:
double[ ][A-Za-z0-9]*[ ]?=(([ ]?[0-9]*d[ ]?/[ ]?[0-9]*;)|[ ]?[0-9]*[ ]?/[ ]?[0-9]*d;)
If it does -not- match this regex, then I add a violation. What this regex will match on is any of the following:
double i=4d / 100;
double i = 4d / 100;
double i = 4 / 100d;
double i = 4/ 100d;
double i = 4 /100d;
double i = 4/100d;
double i=4d / 100;
double i=4 / 100d;
double i=4/100d;
Any of the above will not create a violation. As it is currently written, pretty much if a 'd' isn't used, it'll throw a violation. You'll need to add extra logic to account for the other possible ways of explicitly casting an operand. As I'm writing this, I've just realized that having a 'd' on both operands will most likely throw an exception. Whoops.
And lastly, I could not get StyleCop to display my violation properly. It kept giving me an error about the rule not existing, and even with a second pair of eyes on it, we could not find a solution, so I hacked it. The error shows the name of the rule you were trying to find, so I just put the name of the rule as something descriptive and included the line number in it.
To install the custom rule, build the MathematicalAnalyzer project. Close Visual Studio and copy the DLL into the StyleCop install directory. When you open Visual Studio, you should see the rule in the StyleCop settings. Step 5 and 6 of the article I used shows where to do that.
This only gets one violation at a time throughout the solution, so you'll have to fix the violation it shows, and run StyleCop again to find the next one. There may be a way around that, but I ran out of juice and stopped here.
Enjoy!
This article explains how to set up custom Code Analysis rules that, when you run Code Analysis, can show warnings and what not.
http://blog.tatham.oddie.com.au/2010/01/06/custom-code-analysis-rules-in-vs2010-and-how-to-make-them-run-in-fxcop-and-vs2008-too/
I'm currently reading through C# 4.0 In A Nutshell, and in chapter 2 it states that if an int object has a value of int.MinValue (-2147483648) and the value is decreased, as the value cannot go any lower, it goes to the highest value, int.MaxValue (2147483647):
int a = int.MinValue;
Console.WriteLine(a); //-2147483648
a = a-1;
Console.WriteLine(a); //-2147483648
Console.WriteLine (a == int.MaxValue); // True
The book then goes on to mention how you can protect from this happening using checked.
However, I'm wondering why this is possible? Surely this could cause a lot of issues if its not protected with checked?
Is it not a bit of a flaw in the design? Why would anyone want a minimum value to become a maximum value?
Furthermore, I've noticed VB.NET will throw an 'Arithmetic overflow' instead of letting this happen:
Dim a As Integer
a = Integer.MaxValue
a = a + 1
Response.Write(a) 'Arithmetic overflow exception here
Sometimes it is desired behaviour. Other times, it simply isn't necessary to deal with and check for overflows, as they slow down program execution. Take a game drawing unbound (FPS). At 1000FPS, a small 1ms extra check could have a significant affect on framerate. Other times, it may be expected execution (I've only seen one use of this to date) - it flows on from what happens in C#'s ancestor - C++ and C.
Also, please note that the default behaviour (checked or unchecked) varies between configurations and environments:
If neither checked nor unchecked is used, a constant expression uses
the default overflow checking at compile time, which is checked.
Otherwise, if the expression is non-constant, the run-time overflow
checking depends on other factors such as compiler options and
environment configuration.
Since the code you posted is non-constant (and also due to various environment variables), no checking for overflows is performed.
It is a matter of language design - why this happens has to do with the binary representation of numbers. In .NET this is done with two's complement, hence the overflow issue.
The designers of VB.NET have decided to not allow such overflow/underflow issues.
The designers of C# have decided to leave control to the programmer.
It is possible that your programm automatically check overflow: right click on project file,
select Build, than select Advanced button in right bottom corner. In the opened window check Check Arithmetical Overflow checkbutton.