Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it undefined behavior to form a pointer range from a stack address?

Some C or C++ programmers are surprised to find out that even storing an invalid pointer is undefined behavior. However, for heap or stack arrays, it's okay to store the address of one past the end of the array, which allows you to store "end" positions for use in loops.

But is it undefined behavior to form a pointer range from a single stack variable, like:

char c = 'X';
char* begin = &c;
char* end = begin + 1;

for (; begin != end; ++begin) { /* do something */ }

Although the above example is pretty useless, this might be useful in the event that some function expects a pointer range, and you have a case where you simply have a single value to pass it.

Is this undefined behavior?

like image 893
Channel72 Avatar asked Feb 02 '12 15:02

Channel72


People also ask

Which of the following is invalid pointer arithmetic?

Multiplication or division of a pointer with a constant is not allowed. For example, p1 * p2 or p2 / 5 are invalid. 3.

Does a pointer point to an address or a value?

Pointers are said to "point to" the variable whose address they store. An interesting property of pointers is that they can be used to access the variable they point to directly. This is done by preceding the pointer name with the dereference operator (*). The operator itself can be read as "value pointed to by".

Can a pointer point to two addresses?

No, a single pointer can only point to one thing.

Does pointers have its own address?

The main feature of a pointer is its two-part nature. The pointer itself holds an address. The pointer also points to a value of a specific type - the value at the address the point holds.


1 Answers

This is allowed, the behavior is defined and both begin and end are safely-derived pointer values.

In the C++ standard section 5.7 ([expr.add]) paragraph 4:

For the purposes of these operators, a pointer to a nonarray object 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.

When using C a similar clause can be found in the the C99/N1256 standard section 6.5.6 paragraph 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.


As an aside, in section 3.7.4.3 ([basic.stc.dynamic.safety]) "Safely-derived pointers" there is a footnote:

This section does not impose restrictions on dereferencing pointers to memory not allocated by ::operator new. This maintains the ability of many C++ implementations to use binary libraries and components written in other languages. In particular, this applies to C binaries, because dereferencing pointers to memory allocated by malloc is not restricted.

This suggests that pointer arithmetic throughout the stack is implementation-defined behavior, not undefined behavior.

like image 156
Ben Voigt Avatar answered Nov 15 '22 21:11

Ben Voigt