6

When using a pointer to an array, I've always accessed the elements by using an indexer, such as, myPtr[i] = stuff; however, I was recently looking over BitConverter's implementation and discovered that elements were accessed by doing, *(myPtr + i) = stuff.

Which I thought was quite odd, since both methods (from what I know) do the exact same thing, that is, they return the address of myPtr + i, except (in my opinion) the indexer method looks much more readable.

So why did Microsoft choose to increment pointers the way they did, what's the difference between the two methods (are there performance benefits)?

Sam
  • 7,252
  • 16
  • 46
  • 65

3 Answers3

4

As you stated, they do the same thing.

In fact, when accessing an int*, both ptr[i] and *(ptr + i) syntaxes will skip the bounds check, and point to some memory outside the array bounds if i is greater than the array length.

I'm pretty sure C#, as well as C++, inherited the indexed access to an array pointer using the *(ptr + index) syntax from C. I'm pretty sure that's the only reason why both syntaxes are available.

dcastro
  • 66,540
  • 21
  • 145
  • 155
  • So `myPrt[i]` is just syntactic sugar? No other differences besides that? – Sam Jun 16 '14 at 10:56
  • @Sam Yeah, there shouldn't be any other difference. – dcastro Jun 16 '14 at 11:00
  • @dcastro As far as i remember, using an indexer can give you an `IndexOutOfRangeException`, while `*(ptr + index)` would just point you to some memory outside of the array. – AndreySarafanov Jun 16 '14 at 11:04
  • 3
    @AndreySarafanov Using an indexer would give you an IOR *if* you're accessing an int array, for example. If you're accessing an `int*`, then both `[index]` and `*(ptr + index)` syntaxes would point to some memory outside the array. Both syntaxes will skip bounds-check. – dcastro Jun 16 '14 at 11:11
  • @dcastro Thanks, my bad indeed, should've read the question more carefully. – AndreySarafanov Jun 16 '14 at 11:12
  • There is one interesting difference between C# and C here: In C `i[p]` is valid, it C# it is not. – CodesInChaos Jun 16 '14 at 11:15
  • @CodesInChaos True, [C can be a little weird sometimes](http://stackoverflow.com/questions/381542/with-c-arrays-why-is-it-the-case-that-a5-5a). `i[p]` would be rewritten as `*(i+p)` – dcastro Jun 16 '14 at 11:18
2

From CSharp Language Specification (18.5.3):

A pointer element access of the form P[E] is evaluated exactly as *(P + E). (...) The pointer element access operator does not check for out-of-bounds errors and the behavior when accessing an out-of-bounds element is undefined. This is the same as C and C++.

There are no differences.

gwiazdorrr
  • 6,181
  • 2
  • 27
  • 36
1

To clarify the difference between [] operator of an array and pointer (which discussed under dcastro's answer), you may check output of below code.

unsafe {
    int[] arr = new[] { 1, 2 };
    fixed(int* ptr = arr) {
        for(int i = 0; i < arr.Length + 1; i++) {
            try { System.Console.WriteLine(*(ptr + i)); } catch(Exception e) { System.Console.WriteLine(e.Message); }
            try { System.Console.WriteLine(ptr[i]); } catch (Exception e) { System.Console.WriteLine(e.Message); }
            try { System.Console.WriteLine(arr[i]); } catch (Exception e) { System.Console.WriteLine(e.Message); }
        }
    }
}

Output

1
1
1
2
2
2
0
0
Index was outside the bounds of the array.
Mehmet Ataş
  • 11,081
  • 6
  • 51
  • 78