Thread overview
Is this defined behaviour in D?
Sep 25, 2017
John Burton
Sep 25, 2017
Jonathan M Davis
September 25, 2017
If I have a int* pointer for example, that points to the start of an int array and step through the array until I get the value 123, is it defined in D what happens if you step off the end of the array?

What I might expect to happen is for the code to just keep stepping through sequential memory locations until it finds one that happens to have a 123 in it, until it gets a memory protection fault of some kind, or failing that wrap around memory and go into an infinite loop.

The options are really
1) I can rely on the compiler consistently doing what I'd "expect" on a specific platform.
2) There is some other defined behaviour
3) The compiler can do whatever crazy thing it feels like as this is considered broken code.

I'm not for a moment suggesting this is a good idea, but what I'm really asking is does the D language say anything about this? C++ seems to have chosen (3). Personally I'd prefer (1) but it's most to know if the "standard" such as it is has anything to say on such matters.
September 25, 2017
On 9/25/17 9:06 AM, John Burton wrote:
> If I have a int* pointer for example, that points to the start of an int array and step through the array until I get the value 123, is it defined in D what happens if you step off the end of the array?
> 
> What I might expect to happen is for the code to just keep stepping through sequential memory locations until it finds one that happens to have a 123 in it, until it gets a memory protection fault of some kind, or failing that wrap around memory and go into an infinite loop.
> 
> The options are really
> 1) I can rely on the compiler consistently doing what I'd "expect" on a specific platform.
> 2) There is some other defined behaviour
> 3) The compiler can do whatever crazy thing it feels like as this is considered broken code.
> 
> I'm not for a moment suggesting this is a good idea, but what I'm really asking is does the D language say anything about this? C++ seems to have chosen (3). Personally I'd prefer (1) but it's most to know if the "standard" such as it is has anything to say on such matters.

I would tend to guess 3, but I don't know if the compiler has the capability to reason about it, so the current behavior might be what you expect. I wouldn't count on it though...

-Steve
September 25, 2017
On Monday, September 25, 2017 13:06:56 John Burton via Digitalmars-d-learn wrote:
> If I have a int* pointer for example, that points to the start of an int array and step through the array until I get the value 123, is it defined in D what happens if you step off the end of the array?
>
> What I might expect to happen is for the code to just keep stepping through sequential memory locations until it finds one that happens to have a 123 in it, until it gets a memory protection fault of some kind, or failing that wrap around memory and go into an infinite loop.
>
> The options are really
> 1) I can rely on the compiler consistently doing what I'd
> "expect" on a specific platform.
> 2) There is some other defined behaviour
> 3) The compiler can do whatever crazy thing it feels like as this
> is considered broken code.
>
> I'm not for a moment suggesting this is a good idea, but what I'm really asking is does the D language say anything about this? C++ seems to have chosen (3). Personally I'd prefer (1) but it's most to know if the "standard" such as it is has anything to say on such matters.

I'd have to read through the spec to be sure of what it says, but I'm 99.99% sure that it makes no more guarantees about what happens than C++ does. It's expected that the programmer will do the right thing, and pointer arithmetic is @system precisely so that the programmer can know that they need to look at that code to verify that it's doing the correct thing to avoid memory problems.

But the compiler also isn't going to have any way under normal circumstances to have any clue whether you're iterating past the end of an array when using pointers - that's part of why you would normally use D's dynamic arrays directly rather than use pointer arithmetic, and because you can slice any memory (including malloc-ed memory), you don't have to use pointer arithmetic even if the dynamic array is not GC-allocated. And actually, even in the case of dynamic arrays, the compiler _still_ doesn't know whether you're iterating past the end of the array. It's just that the runtime has checks so that it can throw a RangeError when that happens, and no such checks occur with pointer arithmetic (the necessary information isn't stored with the pointer anyway).

I would fully expect that what you expect to happen will happen under normal circumstances when iterating past the end of an array with a pointer, but the compiler really has no way of making guarantees about what happens - especially when it's not even doing stuff like checking for null pointers (it lets the hardware generate a segfault).

The reality of the matter is that by using pointers instead of dynamic arrays, you're bypassing D's ability to help you make the bug of going past the end of an array defined behavior.

- Jonathan M Davis