
Edward Grace wrote:
On 21 Jul 2009, at 13:42, Celtic Minstrel wrote:
On Tue, Jul 21, 2009 at 6:17 AM, Edward Grace<ej.grace@imperial.ac.uk> wrote:
The standard does not require bounds checking on array subscript, though it seems there's nothing saying it shouldn't bounds check. But there's the alternate v.at(5) notation if you do need bounds checking.
My problem is really that this is 'undefined' behaviour. Surely anything that's 'undefined' is open to error?
My second gripe is that even the idea of undefined behaviour is inconsistent (in MSVC at least). I can quite happily iterate something to .end() (one past the last element) but not to .end()+n --- why?
Because dereferencing an end iterator has undefined behavior.
From what I understand dereferencing either is wrong, why is one more wrong than the other?
It isn't more wrong. The effects are simply more pronounced for one than the other due to some implementation detail on which you cannot count.
From what I can see this prevents the simple creation of a striding iterator, for which the .end() can be at .end() + stride of the underlying vector. One can do it easily by default in g++ as it doesn't hold your hand (exposing you to dereferincing this as being undefined) and leaving that up to you. In MSVC8 it will barf since the debug bounds checking doesn't allow you to keep iterating past the end.
The debug bounds checking is revealing that you are relying on undefined behavior.
Which is the correct treatment?
Perhaps you're unfamiliar with the phrase "undefined behavior." It means that absolutely anything is possible. Each implementation can behave differently, even in different cases. If you avoid doing what has undefined behavior, you'll never encounter such vagaries. If you persist in doing what has undefined behavior, you'll need to account for the differences among compilers -- across versions and operating systems -- and any use cases that lead to different results. Furthermore, you'd have to maintain the non-portable code as each new compiler or use cases presents. If it isn't clear by now, don't dereference an end iterator and don't try to dereference anything past it. Doing so is untenable in portable code. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.