Quote:Original post by LessBread
Had such an instruction been available back when, perhaps bounds checking might have been put into the language from the start.
Quite possibly, but I wasn't talking about that in the bit you quoted. I was just talking about memory usage. Whether or not there is an equivalent to the "bound" instruction, bounds checking necessarily leads to increased memory usage.
Quote:
The Intel docs say that The bounds limit data structure is usually placed just before the array itself, making the limits addressable via a constant offset from the beginning of the array. Because the address of the array already will be present in a register, this practice avoids extra bus cycles to obtain the effective address of the array bounds. So what we're talking about is "2 * sizeof(void*)" extra bytes prepended onto the array, not necessarily to every pointer stored in it.
I said array of pointers for a reason. The bounds checking I was imagining would be to check that the the pointers in the array were valid, not pointers into the array of pointers. When iterating over an array in an idiomatic way, a competent compiler would know only to check the bounds once, so it wouldn't even be an issue.
for (int i = 0; i < size; ++i) { // A competent compiler knows that if array[0] and array[size - 1] are valid, then // any use of array is valid. do_something(array);}
Quote:
What I said was it should be limited to arrays. That's a bit different than saying it only needs to be applied to arrays. It seems to me that a compiler would be able to tell the difference between an array and a pointer, that is, between a constant pointer and a non-constant pointer. Perhaps bounds checking would be better served at compile time than run time.
It's not obvious to me how bounds checking can possibly be applied, in the general case, at compile time in C.
int foo (int *array, int size){ for (int i = 0; i < size; ++i) bar(array);}
How can you check at compile time that foo won't go outside the bounds of array?
Quote:
Would it fall to some_function to check any other pointer for dereferencability as well?
Without cleverness, yes.
Compiling some_function twice, once for a pointer known to be dereferencable and once for a pointer not known to be dereferencable would allow a compiler to make a function call the one which doesn't check the pointer if it knows the pointer is dereferencable. You need to do that for every function which accepts a pointer, and the number of versions you need is 2number of pointer arguments.
That also only solves it for pointer arguments. Functions would still need to check every non-argument pointer they dereference, and pointers accessed via pointer arguments. i.e. in "int do_something (Foo *foo) { return foo->bar->baz; }" the compiler could compile a version of do_something which assumes "foo" is valid, but can it assume bar is a valid pointer? Only if the caller is required to check first. Either way, the check must be performed, because C provides no way to decorate "Foo::bar" to let all functions know it will always point at a valid object.
Quote:
The Intel docs also say that The array index must be greater than or equal to the lower bound and less than or equal to the upper bound plus the operand size in bytes. If I understand that correctly, it covers &x[3] but not &x[7]. The other_function could check if 3 is in bounds before pushing x+3.
&x[3] is not out of bounds. It is a perfectly valid pointer. Only some_function knows that it uses that pointer in a way which has undefined consequences. Only if C enabled a function's signature to distinguish between dereferencable-pointers and dereferencable-and-one-past-the-end-pointers would it be possible to declare some_function in a way which allowed it to assume that all pointers were valid.
[Edited by - Nathan Baum on March 27, 2007 5:27:18 AM]