17

Does c99/c++03 guarantee that &a+1 > &a is always true?

for example, there's a (c-like) std::copy, and

int a = 0 ;
int b[9] ;
std__copy(&a , &a+1 , b) ;

Does this always work?

luke
  • 36,103
  • 8
  • 58
  • 81
exprosic
  • 630
  • 5
  • 17
  • may be the same of http://stackoverflow.com/questions/16233868/pointer-comparisons-with-one-past-the-last-element-of-an-array-object – MOHAMED Apr 30 '13 at 13:28
  • Yes, although the answer @MOHAMED is referrint to talks about an array, it's the same principle for a simple object. – Mats Petersson Apr 30 '13 at 13:29
  • 1
    @MOHAMED, no that isn't the same. There is no question for the case of an array, but for a non array variable there has to be special wording. – AProgrammer Apr 30 '13 at 13:29
  • From memory the answer if UB for C90 and C++98, valid for C11 and C++11 but I don't remember if the clarification was made in time for C99 and C++03 ;-( – AProgrammer Apr 30 '13 at 13:30
  • this link could be useful too http://stackoverflow.com/questions/16234626/pointer-comparisons-with-one-before-the-first-element-of-an-array-object – MOHAMED Apr 30 '13 at 13:37

2 Answers2

17

Yes, C99 has special wording to say that when working with addresses, any given object a will act like an array of 1 item, so that &a+1 is valid (§6.5.6/7):

For the purposes of these operators, a pointer to an object that is not an element of an array behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.

Though the section number is different (§6.3.6), C90 gives the same requirement.

C++ has the same requirement in §5.7/4 (same section number in both C++03 and C++11).

In C++, you can compare addresses of arbitrary objects (of the same type) using std::less, even when the built in < operator would not yield meaningful results (e.g., two objects that are not parts of the same array) (§20.8.5/7):

For templates greater, less, greater_equal, and less_equal, the specializations for any pointer type yield a total order, even if the built-in operators <, >, <=, >= do not.

Also note that although you can form these addresses, and can compare them to the address of the object, you cannot dereference these pointers (well, the compiler probably won't stop you if you try, but the result will be undefined behavior).

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • Interesting, I never knew `std::less` worked for comparing arbitrary addresses. How exactly does the standard guarantee that? – chris Apr 30 '13 at 14:35
3

Yes, that is guaranteed in C++ (don't know about C). The specifics is that a variable of type T is equivalent to an array of a single element of the same type, and you can always obtain a pointer beyond the end of an array.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
  • if it has the same prinicipe of array object you have to mention in the answer that pointer deferencing of `&a+1` is forbidden – MOHAMED Apr 30 '13 at 13:33
  • @MOHAMED: well, the OP doesn't dereference it, so it's not very relevant to the answer either :) – jalf Apr 30 '13 at 13:33
  • I know Just to make him more careful when using such behavior :-) – MOHAMED Apr 30 '13 at 13:35
  • @MOHAMED: The example he has is similar to `std::copy`, and inside that template the `end` iterator is never derreferenced. You are right, and maybe I should be more explicit, but if the intention is passing a single object to an implementation of a function that works on *ranges* (in the sense of pair of iterators) it is perfectly valid. – David Rodríguez - dribeas Apr 30 '13 at 13:38