0

Possible Duplicate:
Take the address of a one-past-the-end array element via subscript: legal by the C++ Standard or not?

const int n = ...;
T a[n];
T* begin = &a[0]; //or just a
T* end = begin + n;

I know this is legal and fine. However I am wondering if the following is undefined behavior or is legal as well. Does the answer depend on type T?

T* end = &a[n];

P.S. This question is a curiosity question, so please refrain from mentioning that vector is a better alternative to arrays and the like :)

Community
  • 1
  • 1
Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434

1 Answers1

0

Yes. It is undefined behavior. No, the type of T doesn't matter.

The accepted answer in the linked duplicate is in error by its very own selection of standard citations. Unfortunately he muddles logic at the end to come up with exactly the opposite conclusion. The note in 3.9.2/3 is contained within a paragraph that is quite clearly talking about the type, not the ability to dereference. The type of the pointer (array+size) is the same "as-if" there was a valid object of type T there; this does not mean that there IS a valid object there and in fact there isn't.

There is a citation in the duplicate of the C99 standard that clearly states that &array[index] will not result in a pointer dereference that is normally implied by array[index]. C99 is not C++ though and I've not seen any equivalent text that says the same thing. It is only by that rule that it is legal in C.

C++0x will contain some of C99, I don't know if this bit is included. You should not consider them the same language.

Most C++ compilers will happily eat it up but you could always run into a compliant compiler that does not.

Edward Strange
  • 40,307
  • 7
  • 73
  • 125
  • Hmm. So how does STL implement end() for vectors? – Roddy Dec 20 '10 at 22:03
  • @Roddy: What's the problem with `end()`? You can't dereference that either. – CB Bailey Dec 20 '10 at 22:05
  • @Charles Bailey - nobody is dereferencing. stl `vector::end()` is usually implemented using `&ptr[size]` like the OP asks. – Roddy Dec 20 '10 at 22:09
  • 2
    @Roddy: Or the alternative that _definitely_ isn't UB: `ptr + size`. – CB Bailey Dec 20 '10 at 22:10
  • @Charles - yes. @Roddy - usually just like the OP did in the first, non-UB causing method. – Edward Strange Dec 20 '10 at 22:11
  • @Noah, @Charles - Thanks - I've read the answers to the linked question now and know more than I wanted to on this topic :-) – Roddy Dec 20 '10 at 22:13
  • The gcc implementation I just checked has class attributes for end in `vector` , `deque` , and `map` already that it just returns, doing no pointer math at all. – Mark B Dec 20 '10 at 22:13
  • @Roddy - I think you'll need to back that claim by citing which implementation does so. – Edward Strange Dec 20 '10 at 22:15
  • @Mark B - yes, but they're still 'calculated' somewhere. The subtlety (which I missed at first) is `ptr + size` vs. `@ptr[size]` – Roddy Dec 20 '10 at 22:16
  • @Noah. My bad: I simply didn't understand the distinction between `ptr+size` and `@ptr[size]`. I'd delete my comment except this comment thread will then make no sense... – Roddy Dec 20 '10 at 22:18