0

As per Pointer arithmetic for void pointer in C, we can't do pointer arithmetic on void pointers.

Also, we can't add, multiply or divide two pointers but we can subtract two pointers.

As per #6.5.6-2 - we can add a pointer and an int type.

Are there any rules for doing pointer arithmetic?

Community
  • 1
  • 1
StackIT
  • 1,172
  • 2
  • 13
  • 25
  • 2
    Well, yes, there's a section in the standard on pointer arithmetic. – chris Oct 11 '13 at 06:01
  • ... and its quite-specific on its rules. – WhozCraig Oct 11 '13 at 06:02
  • What is called “pointer arithmetic” is the rules you just enumerated. There aren't any other arithmetic operations allowed on pointers. – Pascal Cuoq Oct 11 '13 at 06:07
  • @PascalCuoq, But there are extra rules. – chris Oct 11 '13 at 06:11
  • @chris: Where can we find those extra rules? Any links or references will help... – StackIT Oct 11 '13 at 06:13
  • @chris Can you name one extra rule? – BЈовић Oct 11 '13 at 06:13
  • @BЈовић, For example, a pointer addition resulting in a pointer past a one-past-the-end pointer is UB. They're all there in the standard (and drafts). – chris Oct 11 '13 at 06:17
  • @chris I don't think that is an UB. Dereferencing it would cause UB – BЈовић Oct 11 '13 at 06:21
  • @BЈовић Doing the addition is UB. Definitely. – Pascal Cuoq Oct 11 '13 at 06:23
  • 3
    Umm... The question starts by naming the relevant C standard chapter that holds all the answers, then everyone keeps asking where to find the information. – Lundin Oct 11 '13 at 06:28
  • @BЈовић C99 6.5.6:8 “… otherwise, the behavior is undefined” – Pascal Cuoq Oct 11 '13 at 06:28
  • Ok, I was looking into c++ standard, where [6.5.6] is something completely different. This specific item is in [5.7]. – BЈовић Oct 11 '13 at 06:33
  • "Are there any rules for doing pointer arithmetic?" Yes. Don't. (Unless you're writing really low level code, like an implementation of `std::vector`, you shouldn't be using pointer arithmetic.) – James Kanze Oct 11 '13 at 08:28
  • @BЈовић The rules for pointer arithmetic are exactly the same in C++ and in C. The only difference is that in C++, you never need it, except when implementing very low level code; in C, you use it all the time (although generally "hidden" in a `[]` operator). – James Kanze Oct 11 '13 at 08:32
  • @JamesKanze Ok, but I was really confused, since the N3376 has no chapter 6.5.6. btw iterators are very similar to pointers, and I guess the same rules applies – BЈовић Oct 11 '13 at 08:44
  • @BЈовић Good point with regards to iterators. The same rules apply. (But usually, the only "arithmetic" you do with iterators is increment and decrement. And unlike `[]` in C, the overloaded `[]` in the standard containers is not defined in terms of pointer arithmetic.) – James Kanze Oct 11 '13 at 08:48

3 Answers3

3

As per Pointer arithmetic for void pointer in C, we can't do pointer arithmetic on void pointers

Correct, you cannot do that, as per C11 6.5.6/2:

For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to a complete object type and the other shall have integer type.

A void pointer is a pointer to an incomplete type and none of the above.

As per #6.5.6-2 - we can add a pointer and an int type.

Indeed.

Are there any rules for doing pointer arithmetic?

Yes. Those are found in chapter 6.5.6 in the standard.

Lundin
  • 195,001
  • 40
  • 254
  • 396
0

The only things I know of is that if you are subtracting pointers, they have to be the same type and point to "the same block of memory" (two pointers to the same allocation and/or two pointers to the same array). It is also allowed to point "one element beyond" the allocation. Similarly, you can't add more than to one past the end of the block of memory.

It is undefined behaviour to use pointers across blocks of memory because of certain architectures having distinct memory regions, in such a way that a pointer to one region won't trivially (or at all) subtract from another pointer from another region (with a "good" outcome) - for example, OS/2 in 16-bit mode would have a segment register which holds a base-address for a memory region of up to 64KB. Another memory region would have another base-address, and the user-mode code can't get the base-address at all, so there is no way to subtract/add to a pointer to get outside of the region and still "know where you are".

In MOST (now) commonly available architectures, it works just fine to do math for any address in the system, but it's by no means guaranteed by the standard.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • Regarding the last sentence in your answer, there is also the problem of aggressive optimizing compilers. You may know that you are compiling for a flat address space but the compiler will still take advantage of UB for optimization. It does not work fine to do math with any pointer, see http://lwn.net/Articles/278137/ – Pascal Cuoq Oct 11 '13 at 06:25
  • Even without optimization, there is the problem that after `int t[100];`, the expression `t+200 > t+50` may evaluate to false sometimes. The linked article assumes one is familiar with this problem. – Pascal Cuoq Oct 11 '13 at 06:30
-3

The pointer arithmetic is explained here ::

Pointer Arithmetic

Thank you

:::::: Some more explaination :::::::::

Pointers and integers are not interchangeable. (except for 0.) We will have to treat arithmetic between a pointer and an integer, and arithmetic between two pointers, separately.

Suppose you have a pointer to a long.

long *ptrlng;

Binary Operations between a pointer and an integer

1. ptrlng+n is valid, if n is an integer. The result is the following byte address
ptrlng + n*sizeof(long) and not ptrlng + n.
It advances the pointer by n number of longs.

2 ptrlng-n is similar.

Consider two pointers ptr1 and ptr2 which point to the same type of data.

<datatype> *ptr1, *ptr2;

Binary operations between two Pointers

1.Surprise: Adding two pointers together is not allowed!
2.ptr1 - ptr 2 is allowed, as long as they are pointing to elements of the same array. 
The result is
(ptr1 - ptr2)/sizeof(datatype)

In other settings, this operation is undefined (may or may not give the correct answer).

Why all these special cases? These rules for pointer arithmetic are intended to handle addressing inside arrays correctly.

If we can subtract a pointer from another, all the relational operations can be supported!

Logical Operations on Pointers

1. ptr1 > ptr2 is the same as ptr1 - ptr2 > 0,
2. ptr1 = ptr2 is the same as ptr1 - ptr2 = 0,
3. ptr1 < ptr2 is the same as ptr1 - ptr2 < 0,
4. and so on.

Hope this helps.

vkulkarni
  • 849
  • 1
  • 8
  • 12
  • 4
    This is a link-only answer to a bad resource whose authors casually recommend to do illegal arithmetic past the bounds of an array without saying that it's undefined behavior. – Pascal Cuoq Oct 11 '13 at 06:34
  • "Adding two pointers together is not allowed!" - that is really surprising :) What would be result of that operation? – BЈовић Oct 11 '13 at 08:47