5 ms·
> Pointers to Arrays >In a few places, the original source code contains expressions that point one past the last element of an array. Here is a simplified exa
by SV_BubbleTime 5y ago
> Pointers to Arrays
>In a few places, the original source code contains expressions that point one past the last element of an array. Here is a simplified example of the C code:
int array[1024];
int *p;
if (p >= &array[1024]) {
}
>The C standard (see e.g. C11, Section 6.5.6) allows pointers to an element one past the end of the array.
Wait? Why?
I get that char strings in C are null terminated and that might seem like an off by 1 issue if you aren’t paying attention, you still size your string one larger than your string.
What is this all about?
- kimixa 5y agoIt's so you can do exactly what's being done here - see if you have reached the end of the array by comparing the current position pointer. Lots of iterator designs have a special "end" iterator you can compare against but not deference or access - this is just the same for C arrays. The C standard here allows pointers to elements one past the array, but it's still busted if you try to dereference it.
- SV_BubbleTime 5y agoMakes sense. I got what they were doing but in my head combined the C statement of addressing and accessing/dereferencing.
- pix64 5y agoYou can point to the element one pass, but you cannot dereference the pointer.
- SV_BubbleTime 5y agoAh, I get it now. And it’s interesting to me that Rust doesn’t allow that considering it’s not accessing memory (yet, and that’s the whole point I’m sure.
- Diggsey 5y agoPointers in Rust behave the same way. The problem is that the "array index" operator in Rust returns a reference to the indexed element, not a pointer, and references must be safely dereferenceable.
- pwdisswordfish8 5y ago#define COUNT(array) (sizeof(array) / sizeof((array)[0])) int array[1024]; for (int *p = array; p < array + COUNT(array); ++p) { // ... } For the loop to be well-behaved, such pointer formation must be well-defined.
- steveklabnik 5y agoIt is very confusing to me that you've been downvoted in this thread. Anyone who did so want to explain why?
- fallingfrog 5y agoI second that. Why punish someone for asking a pretty understandable question?
- bertr4nd 5y agoI didn’t downvote (I can’t, and I wouldn’t have anyways) but I’ve often see the “Wait? Why?” (Or “wait, what?”) construct carries a connotation of “Why are you doing this insane bad thing?” which people sometimes react negatively to.
- steveklabnik 5y agoAh, that would make sense. I wouldn’t have thought of it that way. Thanks.
- SV_BubbleTime 5y agoYea, maybe it’s that, but every other post I’ve made is also offended someone deeply or so it would seem :)
- defaultname 5y agoC arrays are nothing more than convenient pointer math. array[1024] = &array + sizeof(element) * index (in that case 1024). And while there is some weird post-facto "one past the end" bit in the standard (added long after Quake 3 was made), in any modern compiler you can happily get pointers for illegal indexes. If you have a literally sized array and a literal offset it could warn (e.g. Warray-bounds), but for the vast majority of cases it won't flag at all. Nor would this cause any runtime issues. Because it's just math. And the truth is that without runtime memory protection you can dereference those illegal positions.