21.03.2013 Views

Problem - Kevin Tafuro

Problem - Kevin Tafuro

Problem - Kevin Tafuro

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

which the records begin. Generally, programmers will make sure the item index is<br />

not too high, but they may not realize that the index might be too low!<br />

In addition, it is good to remember that array accesses are rewritten as pointer arithmetic.<br />

For example, arr[x] can index memory before the start of your array if x is<br />

less than 0 once converted to a signed integer.<br />

Size mismatches<br />

You may also encounter problems when an integer type of one size gets converted to<br />

an integer type of another size. For example, suppose that you store an unsigned 64bit<br />

quantity in x, then pass x to an operation that takes an unsigned 32-bit quantity.<br />

In C, the upper 32 bits will get truncated. Therefore, if you need to check for overflow,<br />

you had better do it before the cast happens!<br />

Conversely, when there is an implicit coercion from a small value to a large value,<br />

remember that the sign bit will probably extend out, which may not be intended.<br />

That is, when C converts a signed value to a different-sized signed value, it does not<br />

simply start treating the same bits as a signed value. When growing a number, C will<br />

make sure that it retains the same value it once had, even if the binary representation<br />

is different. When shrinking the value, C may truncate, but even if it does, the sign<br />

will be the same as it was before truncation, which may result in an unexpected<br />

binary representation.<br />

For example, you might have a string declared as a char *, then want to treat the<br />

bytes as integers. Consider the following code:<br />

int main(int argc, char *argv[ ]) {<br />

int x = 0;<br />

if (argc > 1) x += argv[1][0];<br />

printf("%d\n", x);<br />

}<br />

If argv[1][0] happens to be 0xFF, x will end up –1 instead of 255! Even if you<br />

declare x to be an unsigned int, you will still end up with x being 0xFFFFFFFF<br />

instead of the desired 0xFF, because C converts size before sign. That is, a char will<br />

get sign-extended into an int before being coerced into an unsigned int.<br />

Wrap-around<br />

A very similar problem (with the same remediation strategy as those described in previous<br />

subsections) occurs when a variable wraps around. For example, when you<br />

add 1 to the maximum unsigned value, you will get zero. When you add 1 to the<br />

maximum signed value, you will get the minimum possible signed value.<br />

This problem often crops up when using a high-precision clock. For example, some<br />

people use a 32-bit real-time clock, then check to see if one event occurs before<br />

another by testing the clock. Of course, if the clock rolls over (a millisecond clock<br />

Preventing Integer Coercion and Wrap-Around <strong>Problem</strong>s | 91<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!