Monday
Dec082008
Programming Pop Quiz
Monday, December 8, 2008 at 07:39PM These two snippets of code are supposed to advance a pointer along a buffer until they find a double quote character or reach the end of the buffer.
while (input[startPos] != '"' && startPos < input.Length) startPos++;
or
while (startPos < input.Length && input[startPos] != '"') startPos++;
One of them works fine. One throws an exception sometimes. Why?
Rob |
8 Comments | in
development
development
Reader Comments (8)
The first is simply broken you are accessing the indexer before validating the position first. Assuming that startPos is valid to start with for the last iteration of the while loop where no " has been found and you are at the last position in input being:
startPos == input.Lenth - 1
you would increment and access an invalid index +1 after the upper bounds of the input array when reentering the while loop which will throw an exception.
What do I win?
@Alfred - http://panopticoncentral.net/articles/919.aspx
I almost think of the AndAlso as a nested If....if that makes any sense, :)
For the record, I really don't like code like this. It might be the most efficient way to do it, but you should not write code that relies on a language quirk that every reader might not know. My code would be a bit longer, but would be much clearer.
The first piece of code says that while the first character of the input is not null and the start position is less than the length of the string, then increment the start position.
The Second piece of code says that while the start position is less than the length of the string and the first character of the input is not null, then increment the start position.
However if the string is null, then when you ask for the length of the string it will throw an exception because it doesn't have a length. The first piece of code would break out of the loop before it asked for the length, whereas the second piece of code asks for the length first and throws the exception.
The reason this is a language quirk is to do with the way the compiler works. Really what it should do is check both logical statements and crash both times, and the correct code should require an if statement before the while loop:
if (input[startPos] != '"') {
while (startPos < input.Length) startPos++;
}
The reason that rob does this is because when you compile this it makes the code run faster as there isn't an extra if in the code.