If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below. |
|
|
|
Thread Tools | Display Modes |
#11
|
|||
|
|||
|
#12
|
|||
|
|||
Eric Smith wrote in message ...
(Brian Hurt) writes: The solution (to this problem) is automatic bounds checking on array accesses. OK. Here's some C code that is a simplified version of real code I've seen in an application that runs on Linux. The actual code was considerably more complicated, having more arguments and doing various calculations in each function, but I've shown the part that's problematic. It can be argued that the code is simply poorly written, however that was less obvious in the original version than in this simplified version. Anyhow, the point of proposing protection mechanisms is that they should catch cases where the code is poorly written. In one source file: void foo (char *s) { char s2 [40]; bar (s2, s); } In another source file: void bar (char *a, char *b) { sprintf (a, "bar: %s\n", b); } How is the compiler (or linker, or run time system) going to perform automatic bounds checking to solve this problem? In C, you basically can't. You need to store the length of the array in the array itself. And in this case, you do take a branch. A single branch. A single, highly predictable, *cheap* branch (remember, it's mispredictions which are expensive. You only mispredict bounds checking branchs when you fail the bounds check, at which point you are into error recovery anyways, and performance is less of a concern). In many cases, the branch can be eliminated via strength reduction. Consider the following Java-esque code, as an example: for (i = 0; i n; ++i) { a[i] = 0; } Obviously initializing the array a. A naive implementation of bounds checking might look like: for (i = 0; i n; ++i) { if (i a.length) then { a[i] = 0; } else { throw BoundsCheckException; /* or whatever */ } } Do we need to take a branch every loop? No. We can strength reduce the above code to instead look like: limit = min(n, a.length); for (i = 0; i limit; ++i) { a[i] = 0; /* always safe */ } if (n a.length) then throw BoundsCheckException; } Now we're only taking two branchs for the entire loop (one for the min, one to see if we need to throw an exception). We're doing n bounds checks with only 2 branchs, meaning we only need 2/n branches per loop- which approaches zero. Doesn't get there for real code, but it gets there. Note that intelligent C code is already paying much of the cost of strength-reduced bounds checking anyways. Smart C programmers use strncpy and snprintf instead of strcpy and sprintf for exactly these reasions- they *insert* by hand the bounds checking. I still maintain that C and C++ are terrible languages for constructing large scale software systems. I agree. They are not the only languages on the planet, however. Brian |
#13
|
|||
|
|||
|
|
Thread Tools | |
Display Modes | |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Newbie: OC Advice: AMDXP2200 CPU | Donald Bock | Overclocking AMD Processors | 2 | March 12th 05 12:14 AM |
Promise PDC20276 in ATA133 mode: High CPU usage? | Will Dormann | Gigabyte Motherboards | 2 | May 18th 04 02:52 AM |
Finding a fast matrix printer in graphics mode | Andrew Mayo | Printers | 0 | April 15th 04 02:35 PM |
only certain Linux distros can use AMD 64 bit processor | Daeron | General | 33 | February 11th 04 02:52 PM |
Get the Serial Number with Visual Basic | Michael Wittmann | Storage (alternative) | 15 | November 15th 03 06:03 PM |